结合springcloud插件,发起http请求soul网关,体验springcloud代理
一、环境准备
1、soul-bootstrap 引入网关springCloud的插件支持
- 在网关的 pom.xml 文件中引入如下依赖
<!--soul springCloud plugin start-->
<dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-spring-boot-starter-plugin-springcloud</artifactId>
<version>${last.version}</version>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-spring-boot-starter-plugin-httpclient</artifactId>
<version>${last.version}</version>
</dependency>
<!--soul springCloud plugin end-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
- 使用 eureka 作为 springCloud的注册中心,在网关的 pom.xml 继续添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
- 在网关的soul-bootstrap --> application-local.yml文件中 新增如下配置
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/ # 你的eureka地址
instance:
prefer-ip-address: true
2、soul-examples --> soul-examples-springcloud 服务
- 添加如下依赖:
<dependency>
<groupId>org.dromara</groupId>
<artifactId>soul-spring-boot-starter-client-springcloud</artifactId>
<version>${soul.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>${spring-cloud.version}</version>
</dependency>
- soul-examples-springcloud --> application.yml
eureka:
client:
serviceUrl:
defaultZone:http://localhost:8761/eureka/
soul:
springcloud:
admin-url:http://localhost:9095
context-path:/springcloud
3、soul-admin 插件设置
soul-admin --> 插件管理 --> springCloud,设置为开启。
二、启动服务
- soul-examples --> soul-examples-eureka 启动 eureka注册中心
- soul-bootstrap 启动网关服务
- soul-examples --> soul-examples-springcloud 启动 springcloud 服务 8884端口
- soul-examples --> soul-examples-springcloud 启动 springcloud 服务 8885端口
soul-examples --> soul-examples-springcloud 服务接口注册到网关打印的成功信息
2021-01-19 15:37:58.304 INFO 82962 --- [pool-1-thread-1] o.d.s.client.common.utils.RegisterUtils : springCloud client register success: {"appName":"springCloud-test","context":"/springcloud","path":"/springcloud/order/path/**","pathDesc":"","rpcType":"springCloud","ruleName":"/springcloud/order/path/**","enabled":true}
2021-01-19 15:37:58.322 INFO 82962 --- [pool-1-thread-1] o.d.s.client.common.utils.RegisterUtils : springCloud client register success: {"appName":"springCloud-test","context":"/springcloud","path":"/springcloud/order/path/**/name","pathDesc":"","rpcType":"springCloud","ruleName":"/springcloud/order/path/**/name","enabled":true}
查看 soul-admin 接口注册信息
三、测试
通过网关请求 springcloud 接口,请求成功
四、debug请求过程
1、soul-bootstrap 网关引入了 soul-spring-boot-starter-plugin-springcloud,所以soul-bootstrap网关服务启动后会像Spring容器自动注入 SpringCloudPlugin插件。
同时从Spring容器中获取了LoadBalancerClient 负载均衡客户端实例注入到SpringCloudPlugin插件。
public class SpringCloudPluginConfiguration {
@Bean
public SoulPlugin springCloudPlugin(final ObjectProvider<LoadBalancerClient> loadBalancerClient) {
return new SpringCloudPlugin(loadBalancerClient.getIfAvailable());
}
}
2、在SpringCloudPlugin的doExecute方法打上断点发起请求调用,从方法调用栈来看一下调用关系。
1)soul-web – > SoulWebHandler --> execute
2)soul-plugin-base --> AbstractSoulPlugin --> execute
3) soul-plugin-springcloud --> SpringCloudPlugin -->doExecute
3、跟踪 SpringCloudPlugin -->doExecute 方法的执行过程
调用了SpringCloudPlugin插件初始化过程中注入的LoadBalancerClient 负载均衡客户端,实SpringCloud接口服务的负载均衡调用
final ServiceInstance serviceInstance = loadBalancer.choose(selectorHandle.getServiceId());
loadBalancer.choose 方法执行后,选择了8884端口服务(SpringCloud开启了两个服务8884端口,8885端口)
4、SpringCloudPlugin -->doExecute 方法执行完成后,就完成了请求调用,可以看到soul-bootstrap网关控制台打印的请求日志信息。
SpringCloudPlugin -->doExecute 方法执行完成后,只看到了SpringCloudPlugin插件复制均衡器选择的服务调用,没有跟踪到实际发起的请求调用。继续看一下日志中的 WebClientPlugin类。
2021-01-20 15:33:34.699 INFO 55740 --- [erListUpdater-0] c.netflix.config.ChainedDynamicProperty : Flipping property: springCloud-test.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2021-01-20 15:33:34.724 INFO 55740 --- [-work-threads-1] o.d.s.plugin.httpclient.WebClientPlugin : The request urlPath is http://10.7.254.31:8884/order/findById?id=123, retryTimes is 0
2021-01-20 15:33:34.833 WARN 55740 --- [-work-threads-1] io.netty.bootstrap.Bootstrap : Unknown channel option 'SO_TIMEOUT' for channel '[id: 0x55b88438]'
5、soul-plugin-httpclient --> WebClientPlugin --> execute 打上断点,从新跟踪请求。
在这里可以看到完成了完成了SpringCloud服务的请求调用,但是这里并没有看到接口请求响应结果的处理。
6、soul-web --> execute 方法会遍历所有的插件执行,在方法上打上断点可以跟踪到处理请求响应的插件。
WebClientResponsePlugin是处理请求响应结果的插件
7、soul-plugin-httpclient --> WebClientResponsePlugin --> execute 打上断点,这里完成了最终的请求调用。
五、总结
- 1)soul-bootstrap 启动主动注入SpringCloudPlugin插件
- 2)soul-web --> SoulWebHandler --> execute 请求处理
- 3)soul-plugin-base --> AbstractSoulPlugin – > execute 请求处理
- 4)soul-plugin-springcloud --> SpringCloudPlugin --> doExecute --> 负载均衡选择SpringCloud服务
- 5)soul-plugin-httpclient --> WebClientPlugin --> execute 发起请求调用
- 6)soul-plugin-httpclient --> WebClientResponsePlugin --> execute 处理响应结果