我的上一篇文章
1、背景介绍
目前我正在学习的是SpringCloud的有关内容,学习的是Consul作为服务注册中心。在我的上一篇博客当中,我成功搭建了服务提供者模块,然后启动Consul服务注册中心以后,在Consul提供的Web前端浏览器界面访问,可以成功的看到服务提供者模块被注册进了Consul注册中心。
2、本篇博客的目的
本篇博客我将会搭建一个服务消费者的模块,然后注册进Consul服务注册中心。搭建的服务消费者模块的端口号为 90
3、模块的简单的结构
由于我本人只是入门Consul,因此业务逻辑就不会写的十分麻烦了,结构比较的简单,这个微服务模块的结构如下所示:
4、90为端口的服务消费者模块的POM文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>cloud2023</artifactId>
<groupId>com.lanse.springcloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>cloud-consumerconsul-order80</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-consul-discovery -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.lanse.springcloud</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>${project.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
第一个POM依赖,是使用Consul作为服务注册中心所必须的依赖,这个就不需要太多的解释了,太深入的解释我也不会啊,哈哈哈哈哈
下面的依赖都是比较常见的依赖。其中的第二个依赖是我把我的所有模块中会使用到的公共类抽取出来组成了一个模块,然后使用Maven的package命令打成了一个jar包以后,依赖了进来。
剩下的依赖我就不再解释了,是比较常用的,都加上去就可以啦,并且说依赖之间也是没有冲突的。
5、application.yml文件
配置文件的内容如下所示:
server:
port: 90
spring:
application:
name: cloud-consumer-order
cloud:
consul:
host: localhost
port: 8500
discovery:
service-name: ${spring.application.name}
首先就是需要设置一下端口。
然后往下设置一下 spring.application.name属性。 这两个属性都是必须的属性。
然后再向下再设置的就是Consul有关的属性啦。
首先是spring.cloud.consul.host属性
理解这个属性,我觉得应该跟我前面记录过的Eureka作为服务注册中心和ZooKeeper作为服务注册中心对比一下。当使用Eureka作为服务注册中心的时候,有一个eureka.client.service-url.defaultZone属性,这个属性描述的就是注册中心的地址,是一个地址栏中真是输入的地址,比如:http://eureka7001.com:7001/eureka 当使用ZooKeeper作为服务注册中心的时候,有一个spring.cloud.zookeeper.connect-string属性,这个属性描述的也是注册中心的地址,理论上来讲也是可以使用http域名地址的,但是呢,我们都知道 地址栏中我们键入的,其实本质上就是 IP地址+端口号+路径,所以在我的博客的记录中,当我使用ZooKeeper作为服务注册中心的时候,由于我是在我自己的计算机上的VMware上面一个虚拟机CentOS系统上面部署的ZooKeeper服务注册中心,那么就必定有唯一的IP,所以我把spring.cloud.zookeeper.connect-string属性的值就设置为了这个虚拟机的IP地址+ZooKeeper默认的端口号。
今天当使用Consul作为服务注册中心的时候,同样的道理,我们需要指定要注册到的服务注册中心的地址。不过不一样的服务注册中心的配置,还是有一些微小的差异的。比如将服务注册中心的地址的IP和端口号分开,使用HTTP域名方式或者直接就是IP地址的方式。这里的 spring.cloud.consul.host属性描述的就是服务注册中心所在的机器的IP地址。由于我是直接部署在了Windows操作系统下,IP应当是 127.0.0.1,这里我就直接写成了localhost(这也是在系统的hosts文件中有配置的),写成127.0.0.1和localhost都是可以在Consul的Web管理界面看到服务已经注册上去了的,本人亲自测试过了。如果把Consul服务注册中心部署在Linux操作系统之上的话,这个属性的值肯定就需要写为Linux系统的IP地址。
往下,就是spring.cloud.consul.port 配置属性:
这个属性就很容易理解了,上面的属性只是配置了IP地址而已,这个属性是要配置端口号的。Consul跟ZooKeeper一样,服务注册中心也是有默认的端口号的。ZooKeeper服务注册中心默认的端口号是2181,而Consul服务注册中心默认的端口号就是8500
再往下,就是最后一个配置属性:spring.cloud.consul.discovery.service-name
对这个属性,我本人也不是非常的了解。毕竟我现在还是才疏学浅,我只能陈述我所知道的一点点的知识。当写了spring.cloud.consul.discovery.service-name属性的时候,服务注册中心上就会显示spring.cloud.consul.discovery.service-name这个属性的值。如果没有spring.cloud.consul.discovery.service-name这个属性,服务注册中心上就会显示spring.application.name属性的值。至于这两个属性的区别,我也暂时还没有明白,不过按照编码的规范讲的话,可以把这两个属性的值设置为一样的。就像是我的代码中的写法: ${spring.application.name} , 就是把spring.application.name属性的值取了过来。
6、主启动类
代码如下所示:
package com.springcloud;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class OrderConsulMain80 {
public static void main(String[] args) {
SpringApplication.run(OrderConsulMain80.class,args);
}
}
主启动类依旧是老样子,需要加上两个注解,在这里就不多解释了,ZooKeeper跟Consul都是一样的。
7、模块的配置类
package com.springcloud.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
仍然是使用RestTemplate类的方式来发送HTTP请求,调用服务提供者的方法。这个配置文件就是赋予RestTemplate类负载均衡的能力。然后把它转变为一个Bean,使得我们可以注入到别的类当中。作为一个配置类,就像是xml文件一样,需要使用@Configuration注解,这个注解是需要放到类的一级的。最后就是@Bean注解和@LoadBalanced需要放在方法的上面,方法就是简单的返回一个RestTemplate对象。
8、Controller层的类
代码逻辑非常的简单,比较的少,代码如下:
package com.springcloud.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@RestController
@Slf4j
public class OrderConsulController {
public static final String INVOKE_URL="http://consul-provider-payment";
@Resource
private RestTemplate restTemplate;
@RequestMapping("/consumer/payment/consul")
public String paymentInfo(){
String result= restTemplate.getForObject(INVOKE_URL+"/payment/consul",String.class);
return result;
}
}
作为Controller层的代码,@RestController注解是必不可少的。
@Slf4j注解是LomBok插件的,这个就是可以打印日志什么的,在我的这个方法中其实并没有使用到它的功能。
然后就进入到了类当中,首先就是一个静态属性的字符串,这个字符串是必须的。字符串中的
consul-provider-payment就是服务提供者模块注册到服务注册中心上的名字。
后面就是把RestTemplate类的一个对象注入进来了。这个也是必须的,因为需要使用这个对象的方法来发送HTTP请求调用服务提供者模块的方法。
再到后面就是一个方法,依旧使用了getForObject()方法,得到了返回的值,注意这个方法里面的参数,第一个参数是一个请求地址的链接,第二个参数就是一个class。对于第二个参数我本人也不是很理解,我在我Eureka相关的博客中,记录过这个方法,但是当时也看的不是很明白。
最后,如果没有任何以外的话,顺利在命令行窗口使用命令启动Consul服务注册中心(命令详见我的前面的两篇博客),然后启动服务提供者模块的微服务,然后再启动这个服务调用者模块的微服务。
这样的话就可以在Consul的Web页面正常看到有两种服务名字的服务被注册上去。地址栏访问也是符合预期的。本人电脑配置低,启动微服务的话耗费的时间比较的长。
这里我就不再展示具体的执行页面截图了