Java Spring Cloud Alibaba-Nacos 注册中心:(四)使用 Nacos 做注册中心-5100字匠心出品
程序员文章站
2022-03-23 16:53:31
...
使用 Nacos 做注册中心
1.provider 项目的完善
- Provider 现在还是一个空的项目,里面没有任何的数据接口
1.1 添加一个 application.yml 配置文件
- 我们给 provider 添加一个配置文件:
- 文件的名称为:
- 完成创建后,IDEA 能自动的识别该 yml 文件
- 编辑该配置文件,添加如下的配置:
server:
port: 8080
spring:
application:
name: provider-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
配置说明:
- server.port provider 服务端口为 8001 ;
- spring.application.name 服务名称为 provider-service;
- spring.cloud.nacos.server-addr ,指定 Nacos 注册中心的地址;
1.2 添加一个启动类
- Provider 还没有启动类,我们需要给他添加一个。
- 名称为:com.dqcgm.ProviderApplication
- com.dqcgm为包名,ProviderApplicaton 为类的名称,创建完成后,自动的出现:
- 在该类里面添加如下的代码:
@SpringBootApplication // 标记为 SpringBoot 的应用
@EnableDiscoveryClient // 启用服务发现的功能
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class,args) ;
}
}
1.3 添加一个 API 接口
- 提供者通过提供 API 接口供服务提供者调用。
- 在 provider 里面创建一个类:
- 名称为 controller.EchoController
- 成功后,如下图所示:
- 添加一个接口:
@RestController
public class EchoController {
@GetMapping("/echo/{message}")
public ResponseEntity<String> echo(@PathVariable("message") String message){
return ResponseEntity.ok(String.format("hello,%s",message)) ;
}
}
- 该接口将会对访问的人输入一个 hello,xxx
1.4 启动 provider 测试
- 发现 provider 已经启动成功了。
- 打开 Nacos 页面观察 provider 是否上线:
- 服务的提供者已经成功的上线了。
2.consumer 项目的完成
- Consumer 现在还是一个空的项目,里面没有任何的数据接口,也没有对服务的提供者进行调用
2.1 添加一个 application.yml 配置文件
- 名称为:application.yml
- IDEA 能自动的识别该配置文件的:
- 编辑该文件,给该文件添加如下的配置信息:
server:
port: 8090
spring:
application:
name: consumer-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
2.2 添加一个启动类
- Consumer 现在还没有任何的启动类,我们需要给他添加一个
- 名称为:com.dqcgm.ConsumerApplication
- 创建成功后,如下图所示:
- 在该类里面添加如下代码:
@SpringBootApplication // 标记为 SpringBoot 的应用
@EnableDiscoveryClient // 开启服务的发现功能
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class,args) ;
}
}
2.3 服务发现的测试
- 继续改造启动类,在里面添加如下代码:
@Autowired
private DiscoveryClient discoveryClient ;// 快速服务的发现
@GetMapping("/discovery/{serviceName}")
public ResponseEntity<List<String>> discovery(@PathVariable("serviceName") String serviceName){
//通过服务的 ID / 名称得到服务的实例列表
List<ServiceInstance> instances = discoveryClient.getInstances(serviceName);
if(instances==null || instances.isEmpty()){
return ResponseEntity.notFound().build() ;
}
List<String> services = new ArrayList<>(instances.size());
instances.forEach(instance->{
services.add(instance.getHost()+":"+instance.getPort());
});
return ResponseEntity.ok(services) ;
}
- 因为我们在启动类里面添加了接口,所以要必须添加@RestController 该注解来标记该类:
- 最后,我们启动 consumer-service 项目:
- 观察 consumer-service 是否成功的注册到了 Nacos 上面:
- Consumer-service 已经成功了上线了
- 在浏览器输入:
http://localhost:8090/discovery/provider-service - 其中:provider-service 代表服务的名称
- 服务器给我们响应:
- 代表服务已经发现成功
- 输入一个不存在的服务名称:
http://localhost:8090/discovery/provider - 服务器给我们响应:
- 代表,该服务还没有服务的提供者
2.4 远程调用的测试
- 在 consumer,我们调用 provider 里面的 echo 接口
- 继续改造我们的启动类,注册一个 RestTemplate 对象:
//在容器里面注入一个 RestTempalte 对象
@Bean
public RestTemplate restTemplate(){
return new RestTemplate() ;
}
- 调用测试:
@Autowired
private RestTemplate restTemplate ;
@GetMapping("/rpcv1/{message}")
public ResponseEntity<String> rpcV1(@PathVariable("message") String message){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(
"http://localhost:8081/echo/{message}",
String.class,
message
);
if(responseEntity.getStatusCode()==HttpStatus.OK){
return ResponseEntity.ok(String.format("远程调用成功,结果为%s",responseEntity.getBody())) ;
}
return ResponseEntity.badRequest().body("远程调用失败") ;
}
//优化服务提供方地址的灵活性
@GetMapping("/rpcv2/{message}")
public ResponseEntity<String> rpcV2(@PathVariable("message") String message){
List<ServiceInstance> instances = discoveryClient.getInstances("nacos-provider");
if(instances==null || instances.isEmpty()){
return ResponseEntity.badRequest().body("当前服务没有服务的提供者") ;
}
ServiceInstance serviceInstance = instances.get(0);
String instance = serviceInstance.getHost()+":"+serviceInstance.getPort() ;
ResponseEntity<String> responseEntity = restTemplate.getForEntity(
String.format("http://%s/echo/{message}",instance),
String.class,
message
);
if(responseEntity.getStatusCode()==HttpStatus.OK){
return ResponseEntity.ok(String.format("远程调用成功,结果为%s",responseEntity.getBody())) ;
}
return ResponseEntity.badRequest().body("远程调用失败") ;
}
//优化服务提供方的负载均衡
@GetMapping("/rpcv3/{message}")
public ResponseEntity<String> rpcV3(@PathVariable("message") String message){
List<ServiceInstance> instances = discoveryClient.getInstances("nacos-provider");
if(instances==null || instances.isEmpty()){
return ResponseEntity.badRequest().body("当前服务没有服务的提供者") ;
}
ServiceInstance serviceInstance = loadbalance(instances);
System.out.println(serviceInstance);
String instance = serviceInstance.getHost()+":"+serviceInstance.getPort() ;
ResponseEntity<String> responseEntity = restTemplate.getForEntity(
String.format("http://%s/echo/{message}",instance),
String.class,
message
);
if(responseEntity.getStatusCode()==HttpStatus.OK){
return ResponseEntity.ok(String.format("远程调用成功,结果为%s",responseEntity.getBody())) ;
}
return ResponseEntity.badRequest().body("远程调用失败") ;
}
- 其中,loadBalance 的实现逻辑为:
//从一个服务的实例列表里面选择一个服务的实例
private ServiceInstance loadbalance(List<ServiceInstance> instances) {
Random random = new Random(System.currentTimeMillis());
return instances.get(random.nextInt(instances.size())) ;
}
- 重启 Consummer-service:
- 在浏览器里面输入:
http://localhost:8090/rpc/world
服务器给我们相应的数据为:
- 远程调用已经成功
下一篇: 争议机器人未来:做工具还是做“人”?
推荐阅读
-
Spring Cloud Alibaba-使用nacos做注册中心
-
Java Spring Cloud Alibaba-Nacos 注册中心:(五)负载均衡测试
-
Java Spring Cloud Alibaba-Nacos 注册中心:(六)Nacos Discovery 对外暴露的 Endpoint
-
Java Spring Cloud Alibaba-Nacos 注册中心:(四)使用 Nacos 做注册中心-5100字匠心出品
-
Java Spring Cloud Alibaba-Nacos 注册中心:(二)Nacos Server 安装
-
Java Spring Cloud Alibaba-Nacos 注册中心:(三)框架的搭建