做微信的网站叫什么米,做网站前期ps 图多大,湖南省住房和城乡建设厅老网站,下载企业网站一#xff1a;SpringCloud Alibaba介绍
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服 务的必需组件#xff0c;方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。 依托 Spring Cloud Alibaba…一SpringCloud Alibaba介绍
Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。此项目包含开发分布式应用微服 务的必需组件方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。 依托 Spring Cloud Alibaba您只需要添加一些注解和少量配置就可以将 Spring Cloud 应用接 入阿里微服务解决方案通过阿里中间件来迅速搭建分布式应用系统。
主要功能
服务限流降级默认支持 WebServlet、WebFlux OpenFeign、RestTemplate、Spring Cloud Gateway Zuul Dubbo 和 RocketMQ 限流降级功能的接入可以在运行时通过控制台实时修 改限流降级规则还支持查看限流降级 Metrics 监控。 服务注册与发现适配 Spring Cloud 服务注册与发现标准默认集成了 Ribbon 的支持。 分布式配置管理支持分布式系统中的外部化配置配置更改时自动刷新。 消息驱动能力基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。 分布式事务使用 GlobalTransactional 注解 高效并且对业务零侵入地解决分布式事务问题。 阿里云对象存储阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任 何时间、任何地点存储和访问任意类型的数据。 分布式任务调度提供秒级、精准、高可靠、高可用的定时基于 Cron 表达式任务调度服务。 同时提供分布式的任务执行模型如网格任务。网格任务支持海量子任务均匀分配到所有 Workerschedulerx-client上执行。 阿里云短信服务覆盖全球的短信服务友好、高效、智能的互联化通讯能力帮助企业迅速搭建 客户触达通道
二微服务环境搭建
备注将搭建好的环境进行备份以便练习
2.1 数据库准备
创建数据库
2.3 创建工程
结构图 pom
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.yc/groupIdartifactIdspringcloud-alibaba-02/artifactIdpackagingpom/packagingversion1.0-SNAPSHOT/versionmodulesmoduleshop-common/modulemoduleshop-user/modulemoduleshop-product/modulemoduleshop-order/module/modules!-- 父工程 --parentartifactIdspring-boot-starter-parent/artifactIdgroupIdorg.springframework.boot/groupIdversion2.1.3.RELEASE/version/parentpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmaven.compiler.source1.8/maven.compiler.sourcemaven.compiler.target1.8/maven.compiler.target!-- spring-cloud.versionGreenwich.RELEA/spring-cloud.version--!-- spring-cloud-alibaba.version2.1.1.RELEASE/spring-cloud-alibaba.version--spring-cloud-alibaba.version2.1.0.RELEASE/spring-cloud-alibaba.version/propertiesdependencyManagementdependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversionGreenwich.RELEASE/versiontypepom/typescopeimport/scope/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-alibaba-dependencies/artifactIdversion2.1.0.RELEASE/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagement/project2.4 shop-common 模块
1.pom依赖
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdspringcloud-alibaba-02/artifactIdgroupIdcom.yc/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdshop-common/artifactIddependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-jpa/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/dependencydependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.56/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.6/version/dependency/dependencies/project2.结构 3.实体类 Order
package com.yc.domain;import lombok.Data;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.domain* Date 2024/3/4 18:17*/
Entity(name shop_order)
Data
public class Order {IdGeneratedValue(strategy GenerationType.IDENTITY)private Long oid;//订单idprivate Integer uid;//用户idprivate String username;//用户名private Integer pid;//商品idprivate String pname;//商品名称private Double pprice;//商品单价private Integer number;//购买数量
}
Product
package com.yc.domain;import lombok.Data;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.domain* Date 2024/3/4 18:18*/
Entity(name shop_product)
Data
public class Product {IdGeneratedValue(strategy GenerationType.IDENTITY)private Integer pid;//主键private String pname;//商品名称private Double pprice;//商品价格private Integer stock;//库存
}
** User**
package com.yc.domain;import lombok.Data;import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.domain* Date 2024/3/4 18:17*/
Entity(name shop_user)
Data
public class User {IdGeneratedValue(strategy GenerationType.IDENTITY)private Integer uid;//主键private String username;//用户名private String password;//密码private String telephone;//手机号
}
2.5 shop-user 模块
1.pom
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdspringcloud-alibaba-02/artifactIdgroupIdcom.yc/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdshop-user/artifactIddependenciesdependencygroupIdcom.yc/groupIdartifactIdshop-common/artifactIdversion1.0-SNAPSHOT/version/dependency/dependencies
/project2.结构 3.启动类
package com.yc;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc* Date 2024/3/4 18:22*/
SpringBootApplication
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class,args);}
}
4.配置文件 application.yml
server:port: 8071
spring:application:name: service-productdatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql:///hmshop02?serverTimezoneUTCuseUnicodetruecharacterEncodingutf-8useSSLtrueusername: ****password: ****jpa:## 自动生成数据库表配置properties:hibernate:hbm2ddl:auto: updatedialect: org.hibernate.dialect.MySQL5InnoDBDialect2.6 shop_product 模块
1.pom
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdspringcloud-alibaba-02/artifactIdgroupIdcom.yc/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdshop-product/artifactIddependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdcom.yc/groupIdartifactIdshop-common/artifactIdversion1.0-SNAPSHOT/version/dependency/dependencies
/project2.结构 3.启动类
package com.yc;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc* Date 2024/3/4 18:29*/
SpringBootApplication
public class ProductApplication {public static void main(String[] args) {SpringApplication.run(ProductApplication.class,args);}
}
4.配置文件 application.yml
server:port: 18082
spring:application:name: service-productdatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql:///hmshop02?serverTimezoneUTCuseUnicodetruecharacterEncodingutf-8useSSLtrueusername: rootpassword: 123456jpa:properties:hibernate:hbm2ddl:auto: updatedialect: org.hibernate.dialect.MySQL5InnoDBDialect5.ProductController
package com.yc.controller;import com.alibaba.fastjson.JSON;
import com.yc.domain.Product;
import com.yc.service.ProductService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.controller* Date 2024/3/4 18:33*/
RestController
Slf4j
public class ProductController {Autowiredprivate ProductService productService;GetMapping(/product/{pid})public Product product(PathVariable(pid) Integer pid) {Product product productService.findByPid(pid);log.info(查询到商品: JSON.toJSONString(product));return product;}}
6.ProductDao
package com.yc.dao;import com.yc.domain.Product;
import org.springframework.data.jpa.repository.JpaRepository;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.dao* Date 2024/3/4 18:31*/
public interface ProductDao extends JpaRepositoryProduct,Integer {
}
7.ProductService
package com.yc.service;import com.yc.domain.Product;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.service* Date 2024/3/4 18:31*/
public interface ProductService {Product findByPid(Integer pid);
}
8.ProductServiceImpl
package com.yc.service.impl;import com.yc.dao.ProductDao;
import com.yc.domain.Product;
import com.yc.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.service.impl* Date 2024/3/4 18:32*/
Service
public class ProductServiceImpl implements ProductService {Autowiredprivate ProductDao productDao;Overridepublic Product findByPid(Integer pid) {return productDao.findById(pid).get();}
}
9.启动后查看数据库 10.写入测试数据
INSERT INTO shop_product VALUE(NULL,小米,1000,5000);
INSERT INTO shop_product VALUE(NULL,华为,2000,5000);
INSERT INTO shop_product VALUE(NULL,苹果,3000,5000);
INSERT INTO shop_product VALUE(NULL,OPPO,4000,5000);11.通过浏览器访问服务 http://localhost:18082/product/1
2.7 shop-order 模块
1.pom
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdspringcloud-alibaba-02/artifactIdgroupIdcom.yc/groupIdversion1.0-SNAPSHOT/version/parentmodelVersion4.0.0/modelVersionartifactIdshop-order/artifactIddependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdcom.yc/groupIdartifactIdshop-common/artifactIdversion1.0-SNAPSHOT/version/dependency/dependencies/project2.结构 3.启动类
package com.yc;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc* Date 2024/3/4 18:39*/
SpringBootApplication
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}Beanpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}
4.application.yml
server:port: 8091
spring:application:name: service-productdatasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql:///hmshop02?serverTimezoneUTCuseUnicodetruecharacterEncodingutf-8useSSLtrueusername: rootpassword: 123456jpa:properties:hibernate:hbm2ddl:auto: updatedialect: org.hibernate.dialect.MySQL5InnoDBDialect5.OrderController
package com.yc.controller;import com.alibaba.fastjson.JSON;
import com.yc.domain.Order;
import com.yc.domain.Product;
import com.yc.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.controller* Date 2024/3/4 18:45*/
RestController
Slf4j
public class OrderController {Autowiredprivate RestTemplate restTemplate;Autowiredprivate OrderService orderService;//准备买1件商品GetMapping(/order/prod/{pid})public Order order(PathVariable(pid) Integer pid) {log.info(客户下单这时候要调用商品微服务查询商品信息);//通过restTemplate调用商品微服务Product product restTemplate.getForObject(http://localhost:18082/product/ pid, Product.class);log.info(商品信息,查询结果: JSON.toJSONString(product));Order order new Order();order.setUid(1);order.setUsername(测试用户);order.setPid(product.getPid());order.setPname(product.getPname());order.setPprice(product.getPprice());order.setNumber(1);orderService.save(order);return order;}
}
6.OrderDao
package com.yc.dao;import com.yc.domain.Order;
import org.springframework.data.jpa.repository.JpaRepository;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.dao* Date 2024/3/4 18:42*/
public interface OrderDao extends JpaRepositoryOrder,Long {
}
7.OrderService
package com.yc.service;import com.yc.domain.Order;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.service* Date 2024/3/4 18:42*/
public interface OrderService {void save(Order order);
}
8.OrderServiceImpl
package com.yc.service.impl;import com.yc.dao.OrderDao;
import com.yc.domain.Order;
import com.yc.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.service.impl* Date 2024/3/4 18:43*/
Service
public class OrderServiceImpl implements OrderService {Autowiredprivate OrderDao orderDao;Overridepublic void save(Order order) {orderDao.save(order);}}
9启动后浏览器访问 http://localhost:8091/order/prod/1
三 Nacos Discovery–服务治理
什么是服务治理
服务治理是微服务架构中最核心最基本的模块。用于实现各个微服务的自动化注册与发现。
服务注册在服务治理框架中都会构建一个注册中心每个服务单元向注册中心登记自己提供服 务的详细信息。并在注册中心形成一张服务的清单服务注册中心需要以心跳的方式去监测清单中 的服务是否可用如果不可用需要在服务清单中剔除不可用的服务。服务发现服务调用方向服务注册中心咨询服务并获取所有服务的实例清单实现对具体服务实 例的访问。 通过上面的调用图会发现除了微服务还有一个组件是服务注册中心它是微服务架构非常重要 的一个组件在微服务架构里主要起到了协调者的一个作用。注册中心一般包含如下几个功能
服务发现 服务注册保存服务提供者和服务调用者的信息 服务订阅服务调用者订阅服务提供者的信息注册中心向订阅者推送提供者的信息服务配置 配置订阅服务提供者和服务调用者订阅微服务相关的配置 配置下发主动将配置推送给服务提供者和服务调用者服务健康检测 检测服务提供者的健康情况如果发现异常执行服务剔除
3.1 nacos简介
Nacos 致力于帮助您发现、配置和管理微服务。Nacos 提供了一组简单易用的特性集帮助您快速 实现动态服务发现、服务配置、服务元数据及流量管理。 从上面的介绍就可以看出nacos的作用就是一个注册中心用来管理注册上来的各个微服务。
3.2 ncaos实战入门
1.搭建nacos环境
第1步: 安装nacos 备注 以windos系统为例子
下载地址: https://github.com/alibaba/nacos/releases 下载zip格式的安装包然后进行解压缩操作 官方文档https://nacos.io/zh-cn/docs/quick-start.html 第2步修改配置 第3步: 启动nacos
第4步: 访问nacos
打开浏览器输入http://localhost:8848/nacos即可访问服务 默认密码是nacos/nacos
2.将所有模块注册到nacos
shop-order 模块 shop-product 模块 shop-user模块
1 在pom.xml中添加nacos的依赖
!--nacos客户端--
dependency
groupIdcom.alibaba.cloud/groupId
artifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId
/dependency2 在主类上添加EnableDiscoveryClient注解 3 在application.yml中添加nacos服务的地址
spring:cloud:nacos:discovery:server-addr: 127.0.0.1:88484 启动服务 观察nacos的控制面板中是否有注册上来的微服务
3.修改OrderController 实现微服务调用
修改OrderController 实现微服务调用 DiscoveryClient是专门负责服务注册和发现的我们可以通过它获取到注册到注册中心的所有服 务
OrderController中注入依赖
Autowiredprivate DiscoveryClient discoveryClient;将通过restTemplate直接调用商品微服务 改为通过 nacos中获取服务地址
//从nacos中获取服务地址ServiceInstance serviceInstance discoveryClient.getInstances(service-product).get(0);String url serviceInstance.getHost() : serviceInstance.getPort();log.info(从nacos中获取到的微服务地址为: url);
//通过restTemplate调用商品微服务Product product restTemplate.getForObject(http:// url /product/ pid, Product.class);/*//通过restTemplate直接调用商品微服务Product product restTemplate.getForObject(http://localhost:18082/product/ pid, Product.class);*/重新启动订单服务 重启后 访问浏览器 : http://localhost:8091/order/prod/1 四Ribbon实现负载均衡
Ribbon是Spring Cloud的一个组件 它可以让我们使用一个注解就能轻松的搞定负载均衡 链接: Ribbon负载均衡 1.启动两个shop-product 微服务 -Dserver.port18084 2在RestTemplate 的生成方法上添加LoadBalanced注解
package com.yc;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc* Date 2024/3/4 18:39*/
SpringBootApplication
EnableDiscoveryClient
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}BeanLoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}
3修改服务调用的方法
package com.yc.controller;import com.alibaba.fastjson.JSON;
import com.yc.domain.Order;
import com.yc.domain.Product;
import com.yc.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.controller* Date 2024/3/4 18:45*/
RestController
Slf4j
public class OrderController {Autowiredprivate RestTemplate restTemplate;Autowiredprivate OrderService orderService;Autowiredprivate DiscoveryClient discoveryClient;//准备买1件商品GetMapping(/order/prod/{pid})public Order order(PathVariable(pid) Integer pid) {log.info(客户下单这时候要调用商品微服务查询商品信息);//直接使用微服务名字 从nacos中获取服务地址String url service-product01;//通过restTemplate调用商品微服务Product product restTemplate.getForObject(http:// url /product/ pid, Product.class);/*//从nacos中获取服务地址ServiceInstance serviceInstance discoveryClient.getInstances(service-product01).get(0);String url serviceInstance.getHost() : serviceInstance.getPort();log.info(从nacos中获取到的微服务地址为: url);//通过restTemplate调用商品微服务Product product restTemplate.getForObject(http:// url /product/ pid, Product.class);*//*//通过restTemplate调用商品微服务Product product restTemplate.getForObject(http://localhost:18082/product/ pid, Product.class);*/log.info(商品信息,查询结果: JSON.toJSONString(product));Order order new Order();order.setUid(1);order.setUsername(测试用户);order.setPid(product.getPid());order.setPname(product.getPname());order.setPprice(product.getPprice());order.setNumber(1);orderService.save(order);return order;}
}
4.通过修改配置来调整Ribbon的负载均衡策略
# ribbon 实现负载均衡
service-product: # 调用的提供者的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #随机进行负载
5.重启后 访问浏览器 多次范围跟 http://localhost:8091/order/prod/1 shop-order服务日志 shop-product01服务日志
shop-product02服务日志
五Feign实现服务调用
Feign是Spring Cloud提供的一个声明式的伪Http客户端 它使得调用远程服务就像调用本地服务 一样简单 只需要创建一个接口并添加一个注解即可。 Nacos很好的兼容了Feign Feign默认集成了 Ribbon 所以在Nacos下使用Fegin默认就实现了负 载均衡的效果。 链接: Feign服务调用
1 加入Fegin的依赖
!--fegin组件--
dependency
groupIdorg.springframework.cloud/groupId
artifactIdspring-cloud-starter-openfeign/artifactId
/dependency2 在主类上添加Fegin的注解
SpringBootApplication
EnableDiscoveryClient
EnableFeignClients //开启fegin
public class OrderApplication {public static void main(String[] args) {SpringApplication.run(OrderApplication.class, args);}BeanLoadBalancedpublic RestTemplate getRestTemplate() {return new RestTemplate();}
}3 创建一个service 并使用Fegin实现微服务调用
package com.yc.service;import com.yc.domain.Product;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.service* Date 2024/3/5 17:54*/
FeignClient(service-product01)//声明调用的提供者的name
public interface ProudService {//指定调用提供者的哪个方法//FeignClientGetMapping 就是一个完整的请求路径 http://serviceproduct/product/{pid}GetMapping(value /product/{pid})Product findByPid(PathVariable(pid) Integer pid);}
4 修改controller代码并启动验证
package com.yc.controller;import com.alibaba.fastjson.JSON;
import com.yc.domain.Order;
import com.yc.domain.Product;
import com.yc.service.OrderService;
import com.yc.service.ProudService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.controller* Date 2024/3/4 18:45*/
RestController
Slf4j
public class OrderController {Autowiredprivate RestTemplate restTemplate;Autowiredprivate OrderService orderService;Autowiredprivate DiscoveryClient discoveryClient;Autowiredprivate ProudService productService;//准备买1件商品GetMapping(/order/prod/{pid})public Order order(PathVariable(pid) Integer pid) {log.info(客户下单这时候要调用商品微服务查询商品信息);//通过fegin调用商品微服务Product product productService.findByPid(pid);/*//直接使用微服务名字 从nacos中获取服务地址String url service-product01;//通过restTemplate调用商品微服务Product product restTemplate.getForObject(http:// url /product/ pid, Product.class);*//*//从nacos中获取服务地址ServiceInstance serviceInstance discoveryClient.getInstances(service-product01).get(0);String url serviceInstance.getHost() : serviceInstance.getPort();log.info(从nacos中获取到的微服务地址为: url);//通过restTemplate调用商品微服务Product product restTemplate.getForObject(http:// url /product/ pid, Product.class);*//*//通过restTemplate调用商品微服务Product product restTemplate.getForObject(http://localhost:18082/product/ pid, Product.class);*/log.info(商品信息,查询结果: JSON.toJSONString(product));Order order new Order();order.setUid(1);order.setUsername(测试用户);order.setPid(product.getPid());order.setPname(product.getPname());order.setPprice(product.getPprice());order.setNumber(1);orderService.save(order);return order;}
}
5 重启order微服务, 浏览器访问查看效果 http://localhost:8091/order/prod/1
六Sentinel–服务容错
什么是Sentinel
Sentinel (分布式系统的流量防卫兵) 是阿里开源的一套用于服务容错的综合性解决方案。它以流量 为切入点, 从流量控制、熔断降级、系统负载保护等多个维度来保护服务的稳定性。 Sentinel 具有以下特征: 丰富的应用场景Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景, 例如秒杀即 突发流量控制在系统容量可以承受的范围、消息削峰填谷、集群流量控制、实时熔断下游不可用 应用等。 完备的实时监控Sentinel 提供了实时的监控功能。通过控制台可以看到接入应用的单台机器秒 级数据, 甚至 500 台以下规模的集群的汇总运行情况。 广泛的开源生态Sentinel 提供开箱即用的与其它开源框架/库的整合模块, 例如与 Spring Cloud、Dubbo、gRPC 的整合。只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel 完善的 SPI 扩展点Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快 速地定制逻辑。例如定制规则管理、适配动态数据源等
Sentinel 分为两个部分:
核心库Java 客户端不依赖任何框架/库,能够运行于所有 Java 运行时环境同时对 Dubbo / Spring Cloud 等框架也有较好的支持。控制台Dashboard基于 Spring Boot 开发打包后可以直接运行不需要额外的 Tomcat 等 应用容器。
链接: Sentinel 服务容错
6.1服务雪崩效应
在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。如果一个服务出现了 问题调用这个服务就会出现线程阻塞的情况此时若有大量的请求涌入就会出现多条线程阻塞等 待进而导致服务瘫痪。 由于服务与服务之间的依赖性故障会传播会对整个微服务系统造成灾难性的严重后果这就是 服务故障的 “雪崩效应” 。 雪崩发生的原因多种多样有不合理的容量设计或者是高并发下某一个方法响应变慢亦或是某 台机器的资源耗尽。我们无法完全杜绝雪崩源头的发生只有做好足够的容错保证在一个服务发生问 题不会影响到其它服务的正常运行。也就是雪落而不雪崩。
6.2 常见容错方案
要防止雪崩的扩散我们就要做好服务的容错容错说白了就是保护自己不被猪队友拖垮的一些措 施, 下面介绍常见的服务容错思路和组件。
常见的容错思路
常见的容错思路有隔离、超时、限流、熔断、降级这几种下面分别介绍一下。
隔离 它是指将系统按照一定的原则划分为若干个服务模块各个模块之间相对独立无强依赖。当有故 障发生时能将问题和影响隔离在某个模块内部而不扩散风险不波及其它模块不影响整体的 系统服务。常见的隔离方式有线程池隔离和信号量隔离 超时 在上游服务调用下游服务的时候设置一个最大响应时间如果超过这个时间下游未作出反应 就断开请求释放掉线程。
限流 限流就是限制系统的输入和输出流量已达到保护系统的目的。为了保证系统的稳固运行,一旦达到 的需要限制的阈值,就需要限制流量并采取少量措施以完成限制流量的目的。
熔断 在互联网系统中当下游服务因访问压力过大而响应变慢或失败上游服务为了保护系统整 体的可用性可以暂时切断对下游服务的调用。这种牺牲局部保全整体的措施就叫做熔断。 服务熔断一般有三种状态
熔断关闭状态Closed 服务没有故障时熔断器所处的状态对调用方的调用不做任何限制熔断开启状态Open 后续对该服务接口的调用不再经过网络直接执行本地的fallback方法半熔断状态Half-Open 尝试恢复服务调用允许有限的流量调用该服务并监控调用成功率。如果成功率达到预 期则说明服务已恢复进入熔断关闭状态如果成功率仍旧很低则重新进入熔断关闭状 态 降级 降级其实就是为服务提供一个托底方案一旦服务无法正常调用就使用托底方案。
6.3 集成Sentinel
1 在pom.xml中加入下面依赖
!--Sentinel--dependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-sentinel/artifactId/dependency2 编写一个Controller测试使用
package com.yc.controller;import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;/*** Author yc* PackageName springcloud-alibaba-02* Package com.yc.controller* Date 2024/3/5 18:11*/
RestController
Slf4j
public class OrderControllerTest001 {RequestMapping(/order/message1)public String message1() {return message1;}RequestMapping(/order/message2)public String message2() {return message2;}}
6.4 安装Sentinel控制台
Sentinel 提供一个轻量级的控制台, 它提供机器发现、单机资源实时监控以及规则管理等功能。 1 下载jar包,解压到文件夹 https://github.com/alibaba/Sentinel/releases 2 启动控制台
监听端口 sentinel 服务端口地址 项目名称 运行sentinel的jar包
# 直接使用jar命令启动项目(控制台本身是一个SpringBoot项目)
java -Dserver.port8080 -Dcsp.sentinel.dashboard.serverlocalhost:8080 -
Dproject.namesentinel-dashboard -jar sentinel-dashboard-1.7.0.jar3 修改 shop-order模块配置类 ,在里面加入有关控制台的配置
server:port: 8091
spring:application:name: service-order02cloud:nacos:discovery:server-addr: 192.168.93.1:8848sentinel:transport:port: 18081 #跟控制台交流的端口,随意指定一个未使用的端口即可dashboard: localhost:18080 # 指定控制台服务的地址datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql:///hmshop02?serverTimezoneUTCuseUnicodetruecharacterEncodingutf-8useSSLtrueusername: rootpassword: 123456jpa:properties:hibernate:hbm2ddl:auto: updatedialect: org.hibernate.dialect.MySQL5InnoDBDialect# ribbon 实现负载均衡
service-product: # 调用的提供者的名称ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #随机进行负载
第4步: 通过浏览器访问 http://localhost:8091/order/message1
第5步: 通过浏览器访问localhost:18080 进入控制台 ( 默认用户名密码是 sentinel/sentinel )
补充了解控制台的使用原理 Sentinel的控制台其实就是一个SpringBoot编写的程序。我们需要将我们的微服务程序注册到控制台上, 即在微服务中指定控制台的地址, 并且还要开启一个跟控制台传递数据的端口, 控制台也可以通过此端口 调用微服务中的监控程序获取微服务的各种信息
6.5 实现接口限流
1 通过控制台为message1添加一个流控规则 2 通过控制台快速频繁访问, 观察效果
6.6 Sentinel的概念和功能
1.基本概念
资源 资源就是Sentinel要保护的东西 资源是 Sentinel 的关键概念。它可以是 Java 应用程序中的任何内容可以是一个服务也可以是 一个方法甚至可以是一段代码。 我们入门案例中的message1方法就可以认为是一个资源 规则 规则就是用来定义如何进行保护资源的 作用在资源之上, 定义以什么样的方式保护资源主要包括流量控制规则、熔断降级规则以及系统 保护规则。 我们入门案例中就是为message1资源设置了一种流控规则, 限制了进入message1的流量
2 重要功能 Sentinel的主要功能就是容错主要体现为下面这三个 流量控制 流量控制在网络传输中是一个常用的概念它用于调整网络包的数据。任意时间到来的请求往往是 随机不可控的而系统的处理能力是有限的。我们需要根据系统的处理能力对流量进行控制。 Sentinel 作为一个调配器可以根据需要把随机的请求调整成合适的形状。 熔断降级 当检测到调用链路中某个资源出现不稳定的表现例如请求响应时间长或异常比例升高的时候则 对这个资源的调用进行限制让请求快速失败避免影响到其它的资源而导致级联故障。 Sentinel 对这个问题采取了两种手段:
通过并发线程数进行限制 Sentinel 通过限制资源并发线程的数量来减少不稳定资源对其它资源的影响。当某个资源 出现不稳定的情况下例如响应时间变长对资源的直接影响就是会造成线程数的逐步堆 积。当线程数在特定资源上堆积到一定的数量之后对该资源的新请求就会被拒绝。堆积的 线程完成任务后才开始继续接收请求。通过响应时间对资源进行降级 除了对并发线程数进行控制以外Sentinel 还可以通过响应时间来快速降级不稳定的资源。 当依赖的资源出现响应时间过长后所有对该资源的访问都会被直接拒绝直到过了指定的 时间窗口之后才重新恢复。Sentinel 和 Hystrix 的区别 两者的原则是一致的, 都是当一个资源出现问题时, 让其快速失败, 不要波及到其它服务 但是在限制的手段上, 确采取了完全不一样的方法: Hystrix 采用的是线程池隔离的方式, 优点是做到了资源之间的隔离, 缺点是增加了线程 切换的成本。 Sentinel 采用的是通过并发线程的数量和响应时间来对资源做限制。 系统负载保护 Sentinel 同时提供系统维度的自适应保护能力。当系统负载较高的时候如果还持续让 请求进入可能会导致系统崩溃无法响应。在集群环境下会把本应这台机器承载的流量转发到其 它的机器上去。如果这个时候其它的机器也处在一个边缘状态的时候Sentinel 提供了对应的保 护机制让系统的入口流量和系统的负载达到一个平衡保证系统在能力范围之内处理最多的请 求。 总之一句话: 我们需要做的事情就是在Sentinel的资源上配置各种各样的规则来实现各种容错的功 能
6.7 Sentinel规则
1 流控规则
流量控制其原理是监控应用流量的QPS(每秒查询率) 或并发线程数等指标当达到指定的阈值时 对流量进行控制以避免被瞬时的流量高峰冲垮从而保障应用的高可用性。
第1步: 点击簇点链路我们就可以看到访问过的接口地址然后点击对应的流控按钮进入流控规则配 置页面。新增流控规则界面如下: 资源名唯一名称默认是请求路径可自定义 针对来源指定对哪个微服务进行限流默认指default意思是不区分来源全部限制 阈值类型/单机阈值
QPS每秒请求数量: 当调用该接口的QPS达到阈值的时候进行限流线程数当调用该接口的线程数达到阈值的时候进行限流 是否集群暂不需要集群 接下来我们以QPS为例来研究限流规则的配置。
2 简单配置
我们先做一个简单配置设置阈值类型为QPS单机阈值为1。即每秒请求量大于3的时候开始限流。 接下来在流控规则页面就可以看到这个配置
然后快速访问 /order/message1 接口观察效果。此时发现当QPS 1的时候服务就不能正常响 应而是返回Blocked by Sentinel (flow limiting)结果。 3.配置流控模式
点击上面设置流控规则的编辑按钮然后在编辑页面点击高级选项会看到有流控模式一栏。 sentinel共有三种流控模式分别是
直接默认接口达到限流条件时开启限流关联当关联的资源达到限流条件时开启限流 [适合做应用让步]链路当从某个接口过来的资源达到限流条件时开启限流 下面呢分别演示三种模式 直接流控模式 直接流控模式是最简单的模式当指定的接口达到限流条件时开启限流。上面案例使用的就是直接流控 模式。 关联流控模式 关联流控模式指的是当指定接口关联的接口达到限流条件时开启对指定接口开启限流。
链路流控模式 链路流控模式指的是当从某个接口过来的资源达到限流条件时开启限流。它的功能有点类似于针对 来源配置项区别在于针对来源是针对上级微服务而链路流控是针对上级接口也就是说它的粒度 更细
第1步 编写一个service在里面添加一个方法message
Service
public class OrderServiceImplTest001 {SentinelResource(message)public void message() {System.out.println(message);}
}第2步 在Controller中声明两个方法分别调用service中的方法m
RestController
Slf4j
public class OrderControllerTest001 {Autowiredprivate OrderServiceImplTest001 orderServiceImplTest001;RequestMapping(/order/message1)public String message1() {orderServiceImplTest001.message();return message1;}RequestMapping(/order/message2)public String message2() {orderServiceImplTest001.message();return message2;}}第3步: 禁止收敛URL的入口 context 备注如果使用的版本过低需要配置如果是最新版本无需配置 从1.6.3 版本开始Sentinel Web filter默认收敛所有URL的入口context因此链路限流不生效。 1.7.0 版本开始对应SCA的2.1.1.RELEASE)官方在CommonFilter 引入了 WEB_CONTEXT_UNIFY 参数用于控制是否收敛context。将其配置为 false 即可根据不同的 URL 进行链路限流。 SCA 2.1.1.RELEASE之后的版本,可以通过配置spring.cloud.sentinel.web-context-unifyfalse即 可关闭收敛 我们当前使用的版本是SpringCloud Alibaba 2.1.0.RELEASE无法实现链路限流。 目前官方还未发布SCA 2.1.2.RELEASE所以我们只能使用2.1.1.RELEASE需要写代码的形式实 现
配置文件中关闭sentinel的CommonFilter实例化
server:port: 8091
spring:application:name: service-order02cloud:nacos:discovery:server-addr: 192.168.93.1:8848sentinel:transport:port: 9999 # 跟控制台交流的端口随意指定一个未使用的端口即可dashboard: localhost:18080 #指定控制台服务的地址filter:enabled: false添加一个配置类自己构建CommonFilter实例
package com.itheima.config;
import com.alibaba.csp.sentinel.adapter.servlet.CommonFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
Configuration
public class FilterContextConfig {
Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean registration new FilterRegistrationBean();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns(/*);
// 入口资源关闭聚合
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, false);
registration.setName(sentinelFilter);
registration.setOrder(1);
return registration;
}
}第4步配置完重启服务。浏览器分别访问 http://localhost:8091/order/message1 http://localhost:8091/order/message2
第5步: 控制台配置限流规则 第6步: 分别通过 /order/message1 和 /order/message2 访问, 发现关联的接口资源被限流了
4 配置流控效果
快速失败默认: 直接失败抛出异常不做任何额外的处理是最简单的效果 Warm Up它从开始阈值到最大QPS阈值会有一个缓冲阶段一开始的阈值是最大QPS阈值的 1/3然后慢慢增长直到最大阈值适用于将突然增大的流量转换为缓步增长的场景。 排队等待让请求以均匀的速度通过单机阈值为每秒通过数量其余的排队等待 它还会让设 置一个超时时间当请求超过超时间时间还未处理则会被丢弃。