不修改现有代码,通过配置文件扩展 OpenFeign 的功能,扩展的功能如下:
- 支持服务间调用不走负载均衡
- 服务间调用传递 token,token 在请求头或者 url 参数中都可以
- 服务间调用传递请求头中某些 key
- 引入依赖
<dependency>
<groupId>org.juhewu</groupId>
<artifactId>juhewu-openfeign-spring-cloud-starter</artifactId>
<version>1.0.0</version>
</dependency>
- 添加配置
juhewu:
openfeign:
# openfeign 转换成非负载均衡
non-load-balancer:
# 是否启用,默认 false,不启用
enable: true
# 非负载均衡的 url,可以写成网关地址/nginx地址/服务的地址
url: localhost:9999
# 是否跳过前缀,默认 false,不跳过。
# true 时,会拼接成 http://{url}/{path}
# false 或不写时,会拼接成 http://{url}/{service-id}/{path}
skip-prefix: false
# openfeign 传递请求头
pass-header:
# 是否启用,默认 false,不启用
enable: true
# 请求头中需要传递的 keys
keys:
- Test1
- Test2
# openfeign 传递 token
pass-token:
# 是否传递 token,默认是 false,不启用。说明:请求头(Authorization)或 url 中的 access_token 传递到下个服务
enable: true
# url 参数中 token 的名称,默认是 access_token
url-token-name: access_token
以一个简单的微服务系统举例。包含注册中心、网关服务、A服务、B服务。
使用场景:你是开发者在本地开发 B 服务,注册中心、网关、A 服务部署在公共环境,并且是使用 docker / k8s
容器部署。
你现在需要用 B 服务通过 OpenFeign 调用 A 服务,如果不出意外,你是调不通的,因为 A 服务的 ip 是一个 docker 虚拟网络内的一个 ip,你是访问不到该 ip 的,
那怎么解决呢?
既然 B 服务直接调用 A 服务不通,那我们可以找一个 A 服务能调得通的一个地址,比如:B -> 前端 -> 网关 -> A
,通过引入组件并且稍加配置即可实现此功能:
juhewu:
openfeign:
# 转换成非负载均衡
non-load-balancer:
# 是否启用,默认 false,不启用
enable: true
# 非负载均衡的 url。我们配置成前端的地址,前端针对 api 开头的请求会把 api 去掉并转发到网关
url: 192.168.1.200:80/api
# 是否跳过前缀,默认 false,不跳过。如果服务 A 有可以对外访问的地址,那么请求地址就不需要包括服务名,可以将此参数配置成 true
skip-prefix: false
使用场景:服务间调用传递当前登录用户的 token。一般 Token 是放在请求头的Authorization
中,所以如果请求头中有Authorization
,则传递。
有时候为了方便我们可能需要直接把 token 直接放到请求 url 的参数中,所以如果请求 url 的参数中有 access_token,也会传递,可以这么配置:
注意:如果使用 url 的参数传递 token,此 token 会同时写入到请求头的Authorization
中。
juhewu:
openfeign:
# openfeign 传递 token
pass-token:
# 是否传递 token,默认是 false,不启用。说明:请求头(Authorization)或 url 中的 access_token 传递到下个服务
enable: true
# url 参数中 token 的名称,默认是 access_token
url-token-name: access_token
使用场景:服务间用 OpenFeign 调用默认不会传递请求头中的参数,但是当我们需要统一传递一些请求头中的参数时,如:我需要服务间调用传递 Test1 和 Test2,则可以这么配置:
juhewu:
openfeign:
# openfeign 传递请求头
pass-header:
# 是否启用,默认 false,不启用
enable: true
# 请求头中需要传递的 keys
keys:
- Test1
- Test2