目录
搭建微服务项目
-
创建一个聚合服务(总工程)并配置pom.xml
删除无用的只保留以下<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>xxx</artifactId> <version>0.0.1-SNAPSHOT</version> <name>xxx</name> <description>聚合服务</description> <packaging>pom</packaging> <modules> <module>product</module> <module>order</module> <module>conpon</module> 等等。。。。。。 </modules> </project>
-
在总工程下,选择Spring Initializr快速构建一个微服务模块,(common模块可以用maven模式创建)
-
选择每个微服务必备两个组件spring web和open feign
-
以此类推,创建所有微服务模块
-
所有微服务pom.xml导入common模块依赖
<dependency> <groupId>com.example</groupId> <artifactId>ycy-common</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
-
创建数据库,服务自治 每个微服务都对应一个自己的数据库
-
每个微服务在自己的springboot配置文件中配置数据源和服务端口号,并导入相关数据源maven依赖
SpringCloudAlibaba
红色为Alibaba组件,蓝色为SpringCloud原生组件
Springcloud和 Springcloudalibaba和Springboot兼容版本对应:
请严格遵守,否则会报各种错误,详情见https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
在common模块引入依赖管理(之后再引入SpringCloudAlibaba相关组件不需要设置版本)
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
参考:https://github.com/alibaba/spring-cloud-alibaba/blob/2.2.x/README-zh.md
Nacos注册中心
-
再common模块中添加微服务能被发现的maven依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
-
每个微服务在springboot配置文件中配置Nacos Server端地址和自己的服务名
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848 spring.application.name=service-provider server.port=18082
-
每个微服务在springboot启动类上添加@EnableDiscoveryClient 注解开启服务注册与发现功能。
-
下载Nacos Server端并启动,Windows双击startup.cmd
-
访问http://127.0.0.1:8848/nacos 用户名密码默认都是nacos
参考:https://github.com/alibaba/spring-cloud-alibaba/blob/2.2.x/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/readme-zh.md
OpenFeign服务远程调用
OpenFeign是Feign的开源版。看Feign源码可知自带了失败重试机制。
只需要在消费方(调用方)进行配置:
-
导入openfeign依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
启动类上添加注解
@EnableFeignClients
-
创建客户端接口
通常以client包命名
@FeignClient(value = "mall-user") public interface UserFeignClient { @GetMapping("/findById") public User findById(Long id); }
-
使用的时候注入客户端接口即可,类似于注入service和mapper
Nacos配置中心
-
再common模块中添加微服务使用配置中心的maven依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency>
-
每个微服务在resources下新建bootstrap.properties配置文件来配置Nacos配置中心,和当前微服务的名字
spring.application.name=service-ycy spring.cloud.nacos.config.server-addr=127.0.0.1:8848
-
在需要动态获取配置的类上添加@RefreshScope注解,配合@Value(“${ycy}”)注解动态获取配置内容
-
下载Nacos Server端并启动,Windows双击startup.cmd
-
在nacos界面添加一个配置”服务名.properties“,此微服务会优先读取该配置中的内容。实现不用重启微服务就修改配置。
切换配置中心的命名空间和配置分组:
在微服务bootstrap.properties配置文件中添加配置:
spring.cloud.nacos.config.namespace=命名空间ID
#分组配置不写则为默认分组
spring.cloud.nacos.config.group=prod
同时加载多个配置集
在微服务bootstrap.properties配置文件中添加配置:
参考:https://github.com/alibaba/spring-cloud-alibaba/blob/2.2.x/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme-zh.md
SpringCloudGateway API网关
每秒能处理请求数:
SpringCloudGateway使用netty替代tomcat
三大模块
- Route路由
- Predicate断言:条件判断
- Filter过滤器
使用
-
创建一个API网关微服务,并依赖comon模块(排除数据源配置),完成开启nacos注册中心,配置中心等配置(略)(配置同一个普通微服务)
或直接引入依赖:<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
-
在API网关微服务的springboot配置文件中配置路由:
spring: cloud: gateway: routes: - id: baidu_route uri: https://www.baidu.com predicates: - Query=url,baidu - id: qq_route uri: https://www.qq.com predicates: - Query=url,qq
-
测试路由:
参考:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#glossary
Sentinel限流&熔断&降级
Spring Cloud Alibaba Sentinel
-
引入依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency>
-
定义资源,默认为都为受保护的资源。如要自定义资源详情见下方。
-
下载运行Sentinel控制台
下载的控制台版本号要与Sentinel依赖版本号一致,Sentinel 控制台是一个标准的 Spring Boot 应用,以 Spring Boot 的方式运行 jar 包即可。java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
-
在微服务springboot配置文件配置Sentinel控制台地址信息
(8719为默认控制台通信端口号)spring: cloud: sentinel: transport: port: 8719 dashboard: localhost:8080
-
在控制台调整参数(默认所有流控设置保存在内存中,重启失效)
自定义资源
无论哪种方式都需要单独自定义配置限流后的返回内容。
-
基于代码try catch
可以精准到给哪几行代码进行资源保护如限流等操作// 资源名可使用任意有业务语义的字符串,比如方法名、接口名或其它可唯一标识的字符串。 try (Entry entry = SphU.entry("resourceName")) { // 被保护的业务逻辑 // do something here... } catch (BlockException ex) { // 资源访问阻止,被限流或被降级 // 在此处进行相应的处理操作 }
-
基于@SentinelResource注解
在方法上标注@SentinelResource(value = "资源名",blockHandler = "限流/降级时调用的方法名")
blockHandler 函数会在原方法被限流/降级/系统保护的时候调用,而 fallback 函数会针对所有类型的异常。// 原本的业务方法. @SentinelResource(blockHandler = "blockHandlerForGetUser") public User getUserById(String id) { throw new RuntimeException("getUserById command failed"); } // blockHandler 函数,原方法调用被限流/降级/系统保护的时候调用 public User blockHandlerForGetUser(String id, BlockException ex) { return new User("admin"); }
实时监控页面插件支持
-
引入添加Maven依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
-
Spring Boot 2.x 配置文件中添加配置
management.endpoints.web.exposure.include=*
限流
微服务限流
在Sentinel控制台界面配置限流规则。
自定义限流返回内容(非自定义资源):
@Configuration
public class SeckillSentinelConfig implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(), BizCodeEnum.TO_MANY_REQUEST.getMsg());
String s = JSON.toJSONString(error);
System.out.println("自定义的返回" + s);
httpServletResponse.setContentType("text/json;charset=utf-8");
httpServletResponse.getWriter().write(s);
}
}
API网关限流
在API网关层直接进行限流,无需转发到微服务,性能更高。
使用1.7以后的Sentinel和Sentinel控制台版本支持在网关限流。
-
在网关微服务中引入依赖,Sentinel整合Spring Cloud Gateway
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId> <version>2.2.4.RELEASE</version> </dependency>
-
在Sentinel控制台界面进行配置
-
自定义网关限流返回内容
@Configuration public class SentinelGatewayConfig { //响应式编程,Mono Flux public SentinelGatewayConfig(){ GatewayCallbackManager.setBlockHandler(new BlockRequestHandler(){ @Override public Mono<ServerResponse> handlerRequest(ServerWebExchange exchange,Throwable t){ R error = R.error(BizCodeEnum.TO_MANY_REQUEST.getCode(), BizCodeEnum.TO_MANY_REQUEST.getMsg()); String s = JSON.toJSONString(error); ServerResponse body = ServerResponse.ok().body(Mono.just(s), String.class); return body; } }); } }
熔断
-
引入依赖
<dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
-
springboot配置文件打开 Sentinel 对 Feign 的支持:
feign.sentinel.enabled=true
-
编写并指定熔断回调方法fallback,熔断后直接调用该方法
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class) public interface EchoService { @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET) String echo(@PathVariable("str") String str); } class FeignConfiguration { @Bean public EchoServiceFallback echoServiceFallback() { return new EchoServiceFallback(); } } class EchoServiceFallback implements EchoService { @Override public String echo(@PathVariable("str") String str) { return "echo fallback"; } }
降级
降级后会执行熔断回调方法fallback。前端返回限流的自定义返回内容(请求流量过大)。
RT表示一秒内有5个请求都超过多少响应时间触发降级。
时间窗口表示触发降级后持续多久。
参考文档:https://github.com/alibaba/Sentinel/wiki/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8
Sleuth+Zipkin链路追踪
Spring Cloud Sleuth为链路追踪系统,Zipkin为基于Sleuth的可视化界面系统。
-
引入依赖
(Zipkin的依赖包含了Sleuth,所以无需再引入Sleuth依赖)<!--zipkin依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-zipkin</artifactId> </dependency>
-
springboot配置文件中配置
spring: application: name: myService sleuth: sampler: probability: 1 #抽样采样比率,默认0.1为10% zipkin: base-url: http://127.0.0.1:9411/ # 指定了Zipkin服务器的地址 discoveryClientEnabled: false # 不注册成一个服务 sender: type: web # 数据传输方式,web 表示以 HTTP 报文的形式向服务端发送数据,还有kafka 、ACTIVEMQ 等
-
下载安装Zipkin
官方提供了一键脚本curl -sSL https://zipkin.io/quickstart.sh | bash -s java -jar zipkin.jar
如果用 Docker 的话,直接
docker run -d -p 9411:9411 openzipkin/zipkin
-
访问http://127.0.0.1:9411,查看链路调用信息