# cloudAlibaba **Repository Path**: majieat126/cloudalibaba ## Basic Information - **Project Name**: cloudAlibaba - **Description**: 完整的 cloudalibaba搭建 源码 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: dev - **Homepage**: https://gitee.com/zwenbobo_admin/projects - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-07-15 - **Last Updated**: 2025-07-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## springCloud Alibaba 看完这篇就够 这篇文章主要讲述了 : springCloud Alibaba 下的 - [x] Nacos - [x] openFeign - [x] sentinel - [x] seata - [x] springCloud下的Gatetway - [x] skyWalking 等详细搭建和使用过程 ##### 版本依赖: | 名称 | 版本 | 说明| | --- | --- |---| | cloud alibaba |2.2.6 RELEASE |--| | spring boot |2.3.2.RELEASE |--| | spring cloud |Hoxton.SR9 |--| | nacos |1.4.2 |--| | openFeign |10.10.1 |跟随cloud主版本| | sentinel |1.8.1 |--| | seata |1.3.0 |跟随cloud主版本| | Gatetway |2.2.6.RELEASE |--| | skyWalking |9.0.0 |--| --- **项目已放置gitee** ``` https://gitee.com/zwenbobo_admin/cloudalibaba ``` #### 创建父子工程项目 首先整合nacos 和 feign 父工程:cloud-test 子工程:cloud-test-consumer (客户层) 子工程:cloud-test-provider (服务层,远程调研层) **1.父工程pom.xml** ``` 4.0.0 org.springframework.boot spring-boot-starter-parent 2.3.2.RELEASE com.cloud cloud-test 0.0.1-SNAPSHOT cloud-test Demo project for Spring Boot pom cloud-test-consumer cloud-test-provider Hoxton.SR9 2.2.6.RELEASE 8 true org.springframework.boot spring-boot-starter-test test org.springframework.cloud spring-cloud-dependencies ${spring.cloud-version} pom import com.alibaba.cloud spring-cloud-alibaba-dependencies ${spring.cloud.alibaba-version} pom import org.springframework.boot spring-boot-maven-plugin ``` **2.子工程cloud-test-consumer pom.xml** ``` 4.0.0 com.cloud cloud-test 0.0.1-SNAPSHOT cloud-test-consumer 0.0.1-SNAPSHOT cloud-test-consumer Demo project for Spring Boot 8 org.springframework.cloud spring-cloud-starter-openfeign org.springframework.boot spring-boot-starter-web com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery org.springframework.boot spring-boot-starter-web 3.0.0 compile org.springframework.boot spring-boot-maven-plugin ``` **2.1 yml** ``` server: port: 8080 spring: application: name: consumer-server cloud: nacos: server-addr: 127.0.0.1:8848 discovery: username: nacos password: nacos namespace: public ephemeral: false ``` **2.2 启动类中添加注解** ``` //注解式 feign 客户端 @EnableFeignClients ``` **2.3 添加 feign远程接口 下单和获取订单两个方法** ``` @FeignClient(name="provider-server",path = "/item",configuration = FeignConfig.class) public interface ItemFeignService { @GetMapping("/doOrder") String doOrder(); /** * 根据用户ID 获取订单 * @param id * @return */ @GetMapping("/item/{id}") String getItemInfo(@PathVariable(name = "id") String s); } ``` **2.4 controller** ``` @RestController @RequestMapping("/order") public class OrderController { @Resource private ItemFeignService itemFeignService; @GetMapping("/doOrder") public String doOrder() { //1.下单 String info = itemFeignService.doOrder(); System.out.println("下单成功,订单信息为:"+info); //3.模拟返回成功信息 return info; } @GetMapping("/getOrder") public String getOrder() { //1.模拟远程调用获取到到商品信息 String info = itemFeignService.getItemInfo("1"); System.out.println("获取订单信息为:"+info); //3.模拟返回成功信息 return info; } } ``` **3.子工程:cloud-test-providerr pom.xml** ``` 4.0.0 com.cloud cloud-test 0.0.1-SNAPSHOT cloud-test-provider 0.0.1-SNAPSHOT cloud-test-provider Demo project for Spring Boot 8 org.springframework.cloud spring-cloud-starter-openfeign org.springframework.boot spring-boot-starter-web com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery org.springframework.boot spring-boot-maven-plugin ``` **3.1 yml** ``` server: port: 8081 spring: application: name: provider-server cloud: nacos: server-addr: 127.0.0.1:8848 discovery: username: nacos password: nacos namespace: public ephemeral: false ``` **3.2 实现feign 接口的远程服务 controller** ``` @RestController @RequestMapping("/item") public class ItemController { @Value("${server.port}") private String port; /** * 获取商品的信息 * * @param id * @return */ @GetMapping("/doOrder") public String doOrder() { String itemInfo = "订单生成:"+port; return itemInfo; } /** * 获取商品的信息 * * @param id * @return */ @GetMapping("/item/{id}") public String getInfo(@PathVariable(name = "id") String id) { String itemInfo = "订单信息:"+port; return itemInfo; } ``` --- ### Feign 配置 **1.feign 日志配置 在consumer工程编写配置类** ``` package com.cloud.config; /** * @Author wenbo * @Date 2022/12/14 10:35 * * 全局配置: 当使用@Configuration 会将配置作用所有的服务提供方 * 局部配置: 1.通过配置类:如果只想针对某一个服务进行配置,就不要加 @Configuration * 2.通过配置文件yml * **/ @Configuration public class FeignConfig { @Bean public Logger.Level feignLoggerLevel(){ return Logger.Level.FULL; } } ``` **1.2 consumer yml 追加 feign 日志配置** ``` server: port: 8080 spring: application: name: consumer-server cloud: nacos: server-addr: 127.0.0.1:8848 discovery: username: nacos password: nacos namespace: public ephemeral: false #全局 logging: level: com.cloud.feign: debug #单个服务 也可以在服务层 #@FeignClient(name="provider-server",path = "/item",configuration = FeignConfig.class) feign: client: config: provider-server: loggerLevel: BASIC ``` **1.3 负载均衡** 分别启动服务访问地址 可以用idea启动多个服务测试feign负载均衡 //下单 http://localhost:8080/order/doOrder //获取订单 http://localhost:8080/order/getOrder //nacos 控制台查看服务 http://192.168.10.88:8848/nacos/index.html **1.4 feign 契约配置 contract: feign.Contract.Defaul**t ``` feign: client: config: provider-server: loggerLevel: BASIC contract: feign.Contract.Default ``` ==注意:== 该配置需要改变feign 接口中的spring注解未原生注解 **1.5 feign 超时配置** ``` @Bean public Request.Options options(){ return new Request.Options(5000, TimeUnit.MILLISECONDS, 10000,TimeUnit.MILLISECONDS,false); } ``` yml 方式 ``` feign: client: config: provider-server: loggerLevel: BASIC connectTimeout: 5000 readTimeout: 3000 ``` **1.6 feign拦截器** ``` public class CustomFeignInterceptor implements RequestInterceptor { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Override public void apply(RequestTemplate template) { //记录日志 logger.info("feign拦截器"); //修改请求头 template.header("headName","请求头"); //template.query("id","23"); template.uri("/item/9"); } } ``` 代码方式 ``` @Bean public RequestInterceptor basicAuthRequestInterceptor(){ return new CustomFeignInterceptor(); } ``` yml ``` feign: client: config: provider-server: loggerLevel: BASIC connectTimeout: 5000 readTimeout: 3000 requestInterceptors[0]: com.cloud.interceptor.feign.CustomFeignInterceptor ``` --- ### nacos 配置中心实现 **1.子工程中都添加依赖** ``` com.alibaba.cloud spring-cloud-starter-alibaba-nacos-config ``` **2.创建 bootstrap.yml** ``` # DataId 默认使用 `spring.application.name` 配置跟文件扩展名结合(配置格式默认使用 properties), GROUP 不配置默认使用 DEFAULT_GROUP。因此该配置文件对应的 Nacos Config 配置的 DataId 为 nacos-config.properties, GROUP 为 DEFAULT_GROUP spring: application: name: com.cloud.order cloud: nacos: config: server-addr: 127.0.0.1:8848 file-extension: yaml #refresh-enabled: false nacos 将无法感知配置文件改变 namespace: f668dd3a-88a6-43fa-bd7f-360bc6e84cc8 ``` ==注意:== (1).命名空间不写默认读取的是public ,自定义空间要写空间ID值,要不不生效,public没有ID 就写public 或者不写 (2).服务注册发现中也有命名空间,这里指的是服务要注册到那个环境中 (3).nacos 2.0以后的版本可以没有bootstrap文件,直接写application.yml 文件就可以 详细配置官方文档地址: https://github.com/alibaba/spring-cloud-alibaba/blob/2021.x/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc **3.nacos 其他配置** **3.1 通过 spring.cloud.nacos.config.shared-configs来支持多个共享 Data Id 的配置** **3.2 通过 spring.cloud.nacos.config.extension-configs来支持多个共享 Data Id 的配置** ``` cloud: nacos: config: server-addr: 127.0.0.1:8848 file-extension: yaml #refresh-enabled: false nacos 将无法感知配置文件改变 namespace: f668dd3a-88a6-43fa-bd7f-360bc6e84cc8 shared-configs: - data-id: com.cloud.order-shared.yaml refresh: true extension-configs: - data-id: com.cloud.order-extension.yaml refresh: true ``` 下标越大优先级越高 extension > shared ==注意:== 使用 @Value("${user.name}") 获取配置文件的值事不会自动刷新需要加上注解 ``` @RefreshScope ``` ![nacos控制台](doc/images/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_nacos.jpg) --- ### Sentinel 官方文档 ``` https://sentinelguard.io/zh-cn/docs/flow-control.html https://github.com/alibaba/spring-cloud-alibaba/wiki/Sentinel ``` **1.下载控制台** (1)jar 包方式 下载对应的版本jar ``` https://github.com/alibaba/Sentinel/releases ``` 启动命令 ``` java -Dserver.port=8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar ``` 可以配置 win脚本快速启动 start.bat ``` @echo off java -Dserver.port=8858 -Dsentinel.dashboard.auth.username=wenbo -Dsentinel.dashboard.auth.password=123456 -Dserver.servlet.session.timeout=120m -jar sentinel-dashboard-1.8.1.jar pause over ``` (2)源码方式 ``` https://github.com/alibaba/Sentinel/tree/master/sentinel-dashboard ``` 其他命令参数行 ``` 1.-Dsentinel.dashboard.auth.username=sentinel 用于指定控制台的登录用户名为 sentinel 2.-Dsentinel.dashboard.auth.password=123456 用于指定控制台的登录密码为 123456 3.-Dserver.servlet.session.timeout=7200 用于指定 Spring Boot 服务端 session 的过期时间 ``` **2.引入依赖** ``` com.alibaba.cloud spring-cloud-starter-alibaba-sentinel ``` 注解方式依赖 ``` com.alibaba.csp sentinel-core 1.8.1 ``` **3.配置控制台信息** ``` spring: cloud: sentinel: transport: port: 8719 dashboard: localhost:8080 ``` **4.访问控制台** ``` 127.0.0.0:8080 输入用户密码初次访问就会出现监控的接口,然后进行服务的监控,流控,降级设置 ``` **5.sentinem对feign的支持 ,需要配置文件中配置** ``` feign.sentinel.enabled=true ``` **5.1在 @FeignClient 注解中添加EchoServiceFallback** ``` @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"; } } ``` **6.sentinel持久化配置 使用nacos** **6.1.依赖** ``` com.alibaba.csp sentinel-datasource-nacos ``` **6.2 yml配置** ``` spring: sentinel: transport: dashboard: 127.0.0.1:8858 web-context-unify: false #支持链路限流 datasource: sentinel-flow: nacos: server-addr: 127.0.0.1:8848 data-id: sentinel data-type: json rule-type: flow ``` ![sentinel控制台](doc/images/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_sentinel.jpg) --- ### Seata 整合 ``` https://github.com/seata/seata https://seata.io/zh-cn/docs/overview/what-is-seata.html ``` **1.下载相关版本的saata软件包** **1.2使用nacos做配置中心(registry.conf)** ``` registry { # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa type = "nacos" nacos { application = "seata-server" serverAddr = "127.0.0.1:8848" group = "SEATA_GROUP" namespace = "" cluster = "default" username = "nacos" password = "nacos" } } ``` ``` config { type = "nacos" nacos { serverAddr = "127.0.0.1:8848" group = "SEATA_GROUP" namespace = "" username = "nacos" password = "nacos" } } ``` **小case**: ``` 事务分组: 异地机房停电容错 service.vgroupMapping.my_test_tx_group=default #my_test_tx_group 需要与客户端保持一致 default 要跟客户端和 registry.conf 中的cluster 保持一致 (客户端properties配置:spring.cloud.alibabab.seata.tx-service-group=my_test_tx_group) my_test_tx_group可自定义为(gunagzhou.shanghai)对应的client 也要设置 seata.service.vgroup-mapping.projectA=guangzhou ``` **1.2.1 快速将seata配置同步到nacos** ``` 1.将seata源码目录script\config-center config.txt 文件 store.mode=db 并修改数据库连接信息 2.执行script\config-center\nacos nacos-config.sh 脚本即可 ``` **1.3 使用db做事务支持(file.config)** ``` store { ## store mode: file、db、redis mode = "db" ## database store property db { ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc. datasource = "druid" ## mysql/oracle/postgresql/h2/oceanbase etc. dbType = "mysql" driverClassName = "com.mysql.jdbc.Driver" url = "jdbc:mysql://127.0.0.1:3306/seata_cloud" user = "root" password = "123456" minConn = 5 maxConn = 30 globalTable = "global_table" branchTable = "branch_table" lockTable = "lock_table" queryLimit = 100 maxWait = 5000 } } ``` **1.3.1 数据库脚本** ``` https://github.com/seata/seata/tree/master/script/server/db ``` **2.项目配置** **2.1引入依赖** ==注意:如果引入的是springBoot seata 事务不会指定传递要手动配置== ``` com.alibaba.cloud spring-cloud-starter-alibaba-seata ``` **2.2 yml 配置 为了保留配置没有放在nacos中 ,在yml直接配置** ``` seata: registry: #配置seata的注册中心 ,告诉seata client怎么取访问seata serve(TC) type: nacos nacos: server-addr: 127.0.0.1:8848 application: seata-server username: nacos password: nacos group: SEATA_GROUP #配置seata 的配置中心 config: type: nacos nacos: server-addr: 127.0.0.1:8848 username: nacos password: nacos group: SEATA_GROUP enable-auto-data-source-proxy: false ``` ==注意:因为使用的是mybatis-plus 它支持seata 的整合这里设置代理为false,要不事务会被代理两次 默认为true== ``` enable-auto-data-source-proxy: false 如果你使用mybatis-plus 还需要设置 这里使用 at模式 seata: true seata-mode: at ``` **3.生产端代码 controller** ``` @GetMapping("/addOrder2") public String addOrder2() throws TransactionException { String str = iOrderService.createOrder(2L,2L); return str; } ``` **3.1 订单service 通过feign 远程调用库存服务** ``` @Resource private ItemFeignService itemFeignService; @Override @GlobalTransactional(rollbackFor = Exception.class) public String createOrder(Long productId, Long productSpecs) throws TransactionException { Order order = new Order(); order.setOrderNumber("HX123456789"); baseMapper.insert(order); String s = itemFeignService.decStock2(); //int a = 1/0; System.out.println(); return s; } ``` **3.2 库存服务代码 int a = 1/0;不管在订单服务端还是库存服务端异常都可以回滚** ``` @GetMapping("/decStock2") public String decStock2(){ String xid = RootContext.getXID(); System.err.println(xid); Stock stock = iStockService.getById(12L); stock.setProductNum(stock.getProductNum() - 1); iStockService.updateById(stock); int a = 1/0; System.out.println(); return "成功"; } ``` ==特别注意:== ``` 如果使用feign 配置了 fallback 会导致不能回滚 @FeignClient(name="provider-server",configuration = FeignConfig.class,fallback = ItemFeignServiceFallback.class) ``` 处理办法: (1)在ItemFeignServiceFallback 中手动回滚 ``` @Override public String decStock2() throws TransactionException { //手动回滚代码段 GlobalTransactionContext.reload(RootContext.getXID()).rollback(); return "feign限流"; } ``` (2)在全局异常中统一回滚.比如 GloubalExceptionHandler中 --- ### Gatetway ##### 关注稳定与安全 - 全局性流控 - 日志统计 - 防止sql 注入 - 防止web攻击 - 屏蔽工具扫描 - 黑白ip名单 - 证书/加解密处理 ##### 提供更好的服务 - 服务级别流控 - 服务降级流控 - 路由与负载均衡 - 服务过滤 聚合与发现 - 权限验证与用户等级策略 - 业务规则与参数校验 - 多级缓存策略 **中文文档** ``` https://cloud.tencent.com/developer/article/1403887?from=15425 ``` **1.项目搭建** **1.1 创建子项目 cloud-test-gateway** **1.2添加一依赖** ``` org.springframework.cloud spring-cloud-starter-gateway ``` **1.3配置yml** ``` server: port: 8082 spring: application: name: cloud-gateway cloud: gateway: #路由规则 routes: - id: order_route #路由的唯一标识 uri: http://127.0.0.1:8080 #需要转发的地址 #断言规则 路由规则匹配 predicates: - Path=/order-service/** #http://127.0.0.1:8081/order-service/order/add filters: - StripPrefix=1 #转发 前去掉第一层路径 #http://127.0.0.1:8081/order/add ``` **1.4启动gateway 访问原先的接**口 ``` http://192.168.10.88:8082/order-service/order/addOrder2 ``` **2.getaway的内置断言配置** - AfterRoutePredicateFactory //在该日期时间之后发生的请求都将被匹配 ``` - After=2017-01-20T17:42:47.789-07:00[America/Denver] ``` - BoforeRoutePredicateFactory //在该日期时间之前发生的请求都将被匹配。 ``` - Before=2017-01-20T17:42:47.789-07:00[America/Denver] ``` - BetweenRoutePredicateFactory //在datetime1和datetime2之间的请求将被匹配。 ``` - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver] ``` - Cookie 路由断言 Factory ``` - Cookie=chocolate, ch.p ``` - Header 路由断言 Factory ``` - Header=X-Request-Id, \d+ ``` - Host 路由断言 Factory ``` - Host=**.somehost.org,**.anotherhost.org ``` - Method 路由断言 Factory ``` - Method=GET ``` - Path 路由断言 Factory ``` - Path=/foo/{segment},/bar/{segment} ``` - Query 路由断言 Factory ``` - Query=baz,and ``` - RemoteAddr 路由断言 Factory ``` - RemoteAddr=192.168.1.1/24 ``` - 权重 ``` gateway: #discovery: #locator: #enabled: true #路由规则 routes: - id: order_route uri: lb://com.cloud.order predicates: - Weight=group1,8 - id: order_route2 uri: lb://com.cloud.order2 predicates: - Weight=group1,2 ``` **3.自定义路由断言工厂** (1)必须是spring 主键bean (2)类必须加上RoutePredicateFactory (3)必须继承AbstractRoutePredicateFactory (4)必须声明静态的内部类 声明属性来接收配置文件中的断言信息 (5)需要结合shortcutFieldOrder进行绑定 (6)通过apply进行逻辑排断 true 成功 **3.1 自定义代码示例** ``` package com.cloud.gateway.predicates; import lombok.Data; import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import org.springframework.web.server.ServerWebExchange; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; /** * @Author wenbo * @Date 2023/1/5 16:55 **/ @Component public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory { public CheckAuthRoutePredicateFactory() { super(CheckAuthRoutePredicateFactory.Config.class); } @Override public List shortcutFieldOrder() { return Arrays.asList("name"); } @Override public Predicate apply(Config config) { return new GatewayPredicate() { @Override public boolean test(ServerWebExchange exchange) { if (config.getName().equals("wenbo")){ return true; } return false; } }; } /** * 接受断言中的配置信息 */ @Validated @Data public static class Config { private String name; } } ``` **4.gateway 拦截器** - 对于所有匹配的请求,这将向下游请求的头中添加 - x-request-foo:bar header ``` -AddRequestHeader=X-Request-Foo, Bar ``` - 对于所有匹配的请求,这将向下游请求添加foo=bar查询字符串 ``` -AddRequestParameter=foo, bar ``` - 于所有匹配的请求,这会将x-response-foo:bar头添加到下游响应的header中 ``` - AddResponseHeader=X-Response-Foo, Bar ``` - 这将给所有匹配请求的路径加前缀/mypath ``` - PrefixPath=/mypath ``` 还有很多具体可参考官网查看 **4.1自定义getaway路由拦截器代码示例** ``` package com.cloud.gateway.filters; import lombok.Data; import org.springframework.cloud.gateway.filter.GatewayFilter; import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import java.util.Arrays; import java.util.List; /** * @Author wenbo * @Date 2023/1/5 17:44 **/ @Component public class CheckAuthGatewayFilterFactory extends AbstractGatewayFilterFactory { public CheckAuthGatewayFilterFactory() { super(Config.class); } @Override public List shortcutFieldOrder() { return Arrays.asList("value"); } @Override public GatewayFilter apply(Config config) { return (exchange, chain) -> { String name = exchange.getRequest().getQueryParams().getFirst("name"); if (config.getValue().equals(name)){ return chain.filter(exchange); }else{ exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND); return exchange.getResponse().setComplete(); } }; } @Data public static class Config { private String value; } } ``` **4.2 全局拦截器代码示例** ``` import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; /** * @Author wenbo * @Date 2023/1/5 18:10 **/ @Component public class LogFilter implements GlobalFilter { Logger log = LoggerFactory.getLogger(LogFilter.class); @Override public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) { log.info(exchange.getRequest().getPath().value()); return chain.filter(exchange); } } ``` **yml 配置实现 其中还配置了 gateway下的跨域** ``` spring: application: name: cloud-gateway cloud: gateway: #discovery: #locator: #enabled: true #是否启动自动识别nacos 服务 #路由规则 routes: - id: order_route #路由的唯一标识 uri: lb://com.cloud.order #需要转发的地址 lb: 使用nacos中的本地负载均衡 #断言规则 路由规则匹配 predicates: - Path=/order-server/** #- After=2023-01-04T17:42:47.789-07:00[Asia/Shanghai] #- Header=X-Request-Id,\d+ #- Method=Get #- Query=name,wenbo|wenbo2 #http://127.0.0.1:8081/order-service/order/add - CheckAuth=wenbo filters: - StripPrefix=1 #转发 前去掉第一层路径 - AddRequestHeader=X-Request-color,red #添加请求头 #- RedirectTo=302,https://www.baidu.com - CheckAuth=wenbo #http://127.0.0.1:8081/order/add globalcors: corsConfigurations: '[/**]': #允许跨域访问的资源 allowedOrigins: "http://docs.spring.io" #跨域允许来源 allowedMethods: - GET - POST nacos: discovery: server-addr: 127.0.0.1:8848 username: nacos password: nacos logging: config: classpath:logback-spring.xml filePath: /home/local/program/logs/cloudSpring ``` **5.getaway 和 sentinel的配合使用** **5.1 pom加入依赖** ``` com.alibaba.cloud spring-cloud-alibaba-sentinel-gateway com.alibaba.cloud spring-cloud-starter-alibaba-sentinel ``` **5.2 yml配置 sentinel dashboard** ``` sentinel: transport: dashboard: 127.0.0.1:8858 #统一的异常返回 scg: fallback: mode: response response-body: "{code:200,msg:降级了}" ``` **5.2.1 异常也可以通过配置类配置** ``` import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler; import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; import javax.annotation.PostConstruct; /** * @Author wenbo * @Date 2023/1/6 13:54 **/ @Configuration public class GatewayConfig { @PostConstruct public void init(){ BlockRequestHandler blockRequestHandler = new BlockRequestHandler() { //自定义异常 @Override public Mono handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) { return ServerResponse.status(HttpStatus.OK) .contentType(MediaType.APPLICATION_JSON) .body(BodyInserters.fromValue("降级了!")); } }; GatewayCallbackManager.setBlockHandler(blockRequestHandler); } } ``` sentinel 整合gateway后的 控制台有些许变化,总的规则还是不变,多了gateway的功能,实际功能更多,更好 --- ### skyWalking 链路追踪 > Skywalking是一个优秀的国产的开源框架,支持Java、.Net、NodeJs等探针,数据存储支持Mysql、Elasticsearch等,跟Pinpoint一样采用字节码注入的方式实现代码的无侵入,探针采集数据粒度粗,但性能表现优秀,且对云原生支持,目前增长势头强劲,社区活跃。 > 是分布式系统的应用程序性能监视工具,专为微服务,云原生架构和基于容器(Docker,K8S,Mesos)架构而设计,它是一款优秀的APM(Application Performance Management)工具,包括了分布式追踪,性能指标分析和服务依赖分析等。 网站: ``` 官网:http://skywalking.apache.org 下载:http://skywalking.apache.org/downloads Github:https://github.com/apache/skyWalking 文档:https://skywalking.apache.org/docs/skywalking-showcase/next/readme/ 中文文档:https://skyapm.github.io/document-cn-translation-of-skywalking/ ``` **1.搭建 skyWalking** **1.1 先去官网下载 启动包 ,目前已经升级到9.xx 的包,以前8.xx的包自带 agent 目录文件 现在要单独下载** ``` apache-skywalking-apm-9.0.0.tar.gz apache-skywalking-java-agent-8.13.0.tgz ``` **1.1.1 自定义客户端端口** ``` webapp\webapp.yml ``` **1.1.2 skyWalking 存储方式 ,注册方式配置** ``` \config\application.yml #mysql创建好数据库表会在服务启动时创建 注意可能会报数据库连接异常 在\oap-libs\ 目录下添加mysql 连接jar 即可 ``` 1.13 windows 环境idea VM 配置服务接入 ``` -javaagent:D:\tools\apache-skywalking-apm-9.0.0\apache-skywalking-apm-bin\agent\skywalking-agent.jar -DSW_AGENT_NAME=consumer-service -DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 ``` ==注意:== ``` 如果在gateway 接入是不成功的 需要做以下步骤: 将\agent\optional-plugins\apm-spring-cloud-gateway-2.1.x-plugin-8.13.0.jar 复制到\agent\plugins下 ``` linux 下可编写脚本 ``` # !/bin/sh # Skywalking Agent配置 export SW_AGENT_MANE=springboot-skywalking-deno ngont 名字,一般使用`spring.application.nameexport export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800#配置collector地址。 export SW_AGENT_SPAN_LIMIT=2000 #配置链路的最大Span数量,默认为300。 export JAVA_AGENT=-javaagent:/usr/local/soft/apache-skywalking/agent/skywalking-agent.jar java $JAVA_AGENT -jar springboot-skywalking-demo-0.0.1-SNAPSHOT.jar #jar启动 ``` **2.skyWalking 链路参数 和返回值支持** **2.1 添加依赖** ``` org.apache.skywalking apm-toolkit-trace 8.4.0 ``` **2.2 业务方法上添加注解** ``` @Trace @Tag(key = "addOrder2",value = "returnedObj") public String createOrder(Long productId, Long productSpecs) throws TransactionException {} ``` **2.2.1 既有返回值又有参数** ``` @Trace @Tags({ @Tag( key = "createOrder",value = "returnedObj"), @Tag(key = "createOrder",value = "arg[0]")}) public String createOrder(Long productId, Long productSpecs) throws TransactionException {} 或者 @Override @GlobalTransactional(rollbackFor = Exception.class) @Trace @Tag(key = "addOrder2",value = "returnedObj") @Tag(key = "addOrder2",value = "arg[0]") @Tag(key = "addOrder2",value = "arg[1]") public String createOrder(Long productId, Long productSpecs) throws TransactionException {} ``` **3.skyWalking 日志配置 这里配置logback** **3.1 添加依赖** ``` org.apache.skywalking apm-toolkit-logback-1.x 8.10.0 ``` **3.2 在logback.xml的Pattern部分中设置%tid** ``` %d{yyyy-MM-dd HH:mm:ss.SSS} [%tid] [%thread] %-5level %logger{36} -%msg%n ``` **3.3 将日志上传到 skyWalking** 在logback-spring.xml 中追加 ``` %d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n ``` **3.4输出** ``` ``` 注意 : 如果不是本地服务需要配置 \agent\config\agent.config ``` plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:127.0.0.1} plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800} plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760} plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30} ``` **4.skyWalking 告警配置** ``` 在apache-skywalking-apm-bin\config\alarm-settings.yml 中配置规则 和回调接口来触发报警功能 ``` 4.1 参数介绍 ``` include names: 本规则告警生效的实体名称,如服务名,终端名; exclude-names:将此规则作用于不匹配的实体名称上,如服务名,终端名; threshold: 阈值,可以是一个数组,即可以配置多个值; op: 操作符, 可以设定 >, <, =; period: 多久检查一次当前的指标数据是否符合告警规则;以分钟为单位 count: 超过阈值条件,达到count次数,触发告警; silence period:在同一个周期,指定的silence period时间内,忽略相同的告警消息; ``` **5.skyWalking面板** **5.1仪表盘** ![仪表盘](doc/images/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_sky1.jpg) **5.2 拓补图** ![拓补图](doc/images/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_sky2.jpg) **5.3 调用链路** ![调用链路](doc/images/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_sky3.jpg) **5.4性能剖析,添加剖析的接口** ![性能剖析,添加剖析的接口](doc/images/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_sky4.jpg) **5.5日志** ![日志](doc/images/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_sky5.jpg)