Spring Cloud Tencent版本:1.5.3-Hoxton.SR9
服务注册与发现需在pom文件中引入:(polaris-discovery:北极星服务发现;openfeign:远程服务调用)
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-polaris-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
新建一个ServerB的Module,用来实现服务间的接口调用:
@SpringBootApplication
@EnableFeignClients
//启用feign
public class ServerBApplication {
public static void main(String[] args) {
SpringApplication.run(ServerBApplication.class, args);
}
/**
* 添加@LoadBalaced注解使得服务B远程调用服务A->存在多个A服务时可以实现负载均衡
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
创建一个正常的ServerB服务的Controller接口类(通过B服务的配置可直接访问):
@RestController
@RequestMapping("/serverb")
public class ServerbController {
private static Logger LOG = LoggerFactory.getLogger(ServerbController.class);
@Value("${server.port:0}")
private int port;
@GetMapping("/info")
public String info(@RequestHeader(value = "ak",required = false) String ak) {
LOG.info("Gateway Example Callee [{}] is called.", port);
return String.format("Gateway Example Callee [%s] is called.", port);
}
}
添加 @EnableFeignClients 注解开启Feign、
关键点:
创建一个RemoteService接口类,并添加@FeignClient()注解来指定Feign远程调用的“服务名称”;fallbackFactory为笔者指定的特定服务降级指定方法类。
@FeignClient(name = "ServerA", fallbackFactory = OpenfeignRestfallbackFactory.class)
public interface RemoteService {
@GetMapping("/servera/info")
AjaxResult info(@RequestHeader(value = "ak",required = false) String ak);
}
@Slf4j
@RestController
@RequestMapping("/bremotea")
public class RemoteController {
@Resource
private RemoteService remoteService;
@Autowired
private RestTemplate restTemplate;
/**
* 由于我们在RemoteService中加入的@FeignClient(name = "ServerA")注解,已经帮我们对应到ServerA
* 找到对应ServerA服务提供者进行调用
*/
@GetMapping("/info")
public AjaxResult info(@RequestHeader(value = "ak",required = false) String ak, HttpServletRequest request){
String name = Thread.currentThread().getName();
System.out.println(name);
return remoteService.info(ak);
}
/**
* 利用@LoadBalanced可在RestTemplate里使用应用的名字调用服务
*/
@GetMapping("/info2")
public AjaxResult info2(@RequestHeader(value = "ak",required = false) String ak){
log.info("ak:{}",ak);
ResponseEntity<AjaxResult> entity = restTemplate.getForEntity(
"http://ServerA/servera/info",
AjaxResult.class);
return entity.getBody();
}
}
通过ServerB服务的端口调用ServerA服务的接口,即为远程调用的实现。
bootstrap.yml 配置文件中加入以下配置内容:
server:
session-timeout: 1800 #此处设置超时时间
port: 8084 #当前服务端口号(此处我们设置ServerB的端口号为8084,ServerA的端口号为8083)
spring:
application:
name: ServerB #当前服务名称
cloud:
tencent:
metadata:
content:
env: green #静态元数据(元数据参考文档:https://blog.csdn.net/liu_dong_kang/article/details/98474570)
polaris:
address: grpc://127.0.0.1:8091 #本地搭建的北极星服务地址
namespace: inlin-tencent #北极星属性-命名空间(可以分组管理各个应用服务)
在bootstrap.yml配置应用服务名、北极星地址、北极星命名空间后,启动服务,便可在北极星的控制台发现两个服务已经被我们注册(ServerA服务为自定义的命名空间;ServerB服务为默认的命名空间)
然后点击进入想要管理的服务,便可监测该服务的ip、端口、服务是否正常开启的健康状态
由于服务发现与服务注册通常是在bootstrap.yml将服务与北极星的环境配置好即可基本使用,所以这块目前还没有深究。有特别需求调用的可以参考官方提供的文档:
传送门:Spring Cloud Tencent Discovery 使用文档 · Tencent/spring-cloud-tencent Wiki · GitHub
拓展使用
元数据
元数据定义
服务实例通常带有一系列的标签信息,例如实例所属的机房信息、地域信息、环境信息等,这些信息统称为服务实例的元信息。实例注册到注册中心时,会带上自身的元数据信息。当消费方从注册中心获取到实例时,既可以同时获取到每个实例的元信息。
元数据来源
在 Spring Cloud 项目里的 application.yml 中配置以下内容:
spring:
cloud:
tencent:
metadata:
content:
idc: shanghai
应用在启动注册时,会自动读取配置文件并带上 idc=shanghai 和 env=dev1 两个元数据信息。
通过配置文件的方式为最直接的方式,但是这种方式有一个最大的弊端,就是设置不同元数据值时需要重新编译打包。本质上的原因就是:大部分的元数据信息属于部署环境的信息或者叫机器的信息,而不是应用静态代码的信息。
众所周知,Spring Boot 应用配置文件定义的配置项都可以通过 -D 启动参数覆盖,例如通过以下方式覆盖 env 值为 dev2 :
Java -jar -Dspring.cloud.tencent.metadata.content.env=dev2 demo.jar
通过启动参数的方式,可以在启动时动态修改元数据信息,而不用重新打包,从而解决了方式一的弊端。
但是这种方式也有弊端,就是谁负责修改启动脚本,加上 -D 参数呢?
大部分情况下,Java -jar 启动命令都放在项目里的 start.sh 脚本里,那也就是说,每次需要增加 -D 参数都要修改 start.sh,这本身也会增加维护成本。
环境变量的方式则完全跟运行的应用解耦,是完完全全的机器信息。Spring Cloud Tencent 约定了前缀 SCT_METADATA_CONTENT_ 的环境变量为应用的元数据信息。例如:
SCT_METADATA_CONTENT_IDC=shanghai
应用在启动时,则会自动携带 IDC=shanghai 和 ENV=dev 的元数据。
通过环境变量的方式,paas 平台在拉起一台虚拟机或者一个容器 Pod 时,只需要设置相应的环境变量即可。而应用自身无需做任何其它事情。
grep "Loaded static metadata info" xx.log
前面三种方式为 SCT(Spring Cloud Tencent 的缩写) 内置的方式,但是并不一定符合每个公司自己的规范或者实现。例如:
所以 SCT 定义了一个 SPI,方便用户自己实现元数据来源。SCT 在注册前,回调 SPI 获取元数据信息,并注册到注册中心。
控制台调整实例的权重、下线实现等操作
如下图所示,可以在控制台上对实例进行一系列管控操作,例如隔离实例,调整实例权重等。
心跳上报
Spring Cloud Tencent 会异步定时 5s 向北极星服务端发送心跳请求,表示当前实例是存活的状态。为了更准确的表达“健康”的语义,用户可以配置 spring.cloud.polaris.discovery.health-check-url 配置项。配置 health-check-url 之后,Spring Cloud Tencent 在向北极星服务端发送心跳之前,先自检一下健康状态,如果健康才会发送心跳请求。
自定义参数
除了控制台页面可以调整参数以外,Spring Cloud Tencent Discovery 提供了很多自定义参数满足各类场景。以权重随机策略为例,您可以在项目里的 bootstrap.yml 配置文件里配置 spring.cloud.polaris.weight 既可以调整权重值(默认为 100)。
注册的 IP 地址,默认情况下 Spring Boot 会自动获取 IP 地址无需指定 IP 地址,当需要自定义 IP 地址时才需要设置 | |||
spring.cloud.polaris.discovery.service-list-refresh-interval |
参考文献:Spring Cloud Tencent Discovery 使用文档 · Tencent/spring-cloud-tencent Wiki · GitHub