SpringCloud_H(服务注册和发现)
1、父类编写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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu</groupId>
<artifactId>springcloud</artifactId>
<version>1.0-SNAPSHOT</version>
<modules>
<module>cloud-provider-payment8001</module>
</modules>
<packaging>pom</packaging>
<!-- 统一管理jar包版本 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.16</druid.version>
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
</properties>
<!-- 子模块继承之后,提供作用:锁定版本+子modlue不用写groupId和version -->
<dependencyManagement>
<dependencies>
<!--spring boot 2.2.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud alibaba 2.1.0.RELEASE-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
2、provider-payment-8001 (提供者)
- maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>
<!--mysql-connector-java-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- controller
@RestController
@Slf4j
public class PaymentController {
@Autowired
private PaymentService paymentService;
//向数据局插入数据
@PostMapping("/payment/create")
public CommonResult create(Payment payment){
int result = paymentService.create(payment);
log.info("插入的结果:" + result);
if (result > 0){
//如果成功插入,返回状态码 200
return new CommonResult(200,"插入数据库成功",result);
}else {
return new CommonResult(444,"插入数据库失败",result);
}
}
//从数据库查询数据
@GetMapping("/payment/getPaymentById/{id}")
public CommonResult getPaymentById(@PathVariable("id") long id){
Payment payment = paymentService.getPaymentById(id);
if (payment != null){
log.info("查询的结果:"+ payment.toString());
return new CommonResult(200,"查找成功",payment);
}else {
return new CommonResult(444,"查找失败");
}
}
}
3、consumer-80 (消费者)
- maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- application.yml
server:
port: 80
- RestTemplate:
- RestTemplate提供了多种便捷访问远程Http服务的方法,是一种简单便捷的访问restful服务模板类,是spring提供的用于访问Rest服务的客户端模板工具类,使用consumer-80到provider-8001的远程调用
- 编写RestTeplate配置文件
package com.atguigu.springcloud.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class ApplicationContextConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
- controller 调用provider服务的接口
package com.atguigu.springcloud.controller;
import com.atguigu.springcloud.entity.CommonResult;
import com.atguigu.springcloud.entity.Payment;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
@Slf4j
public class OrderController {
//提供者provider的url地址
public static final String PAYMENT_URL = "http://localhost:8001";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/create")
public CommonResult<Payment> create(Payment payment){
/***
* 参数1: 请求地址
* 参数2: 请求参数
* 参数3: 响应转换的对象类型
*/
return restTemplate.postForObject(PAYMENT_URL+"/payment/create",payment,CommonResult.class);
}
@GetMapping("/consumer/payment/get/{id}")
public CommonResult<Payment> getPayment(@PathVariable("id") long id){
return restTemplate.getForObject(PAYMENT_URL+"/payment/getPaymentById/"+id,CommonResult.class);
}
}
4、工程重构
-
项目中存在相同的代码(如entity包下面的实体类),造成代码冗余,可以进行重构
-
创建工程 cloud-api-commons
-
maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.0</version>
</dependency>
</dependencies>
- 将privider 和 consumer 中的实体类文件entity 拷贝到当前项目中
- 使用maven打包发布到本地仓库(install)
- 删除provider 和 consumer 中的entity,引入cloud-api-commons
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
5、Eureka服务注册和发现
5.1、Eureka基础知识
-
服务治理
- springcloud 封装了Netflix公司开发的Eureka模块来实现服务治理
- 在传统的rpc远程调用框架中,管理每个服务与微服务之间依赖关系比较复杂,管理比较复杂,所有需要使用服务治理,管理服务于服务之间的依赖关系,可以实现服务调用、负载均衡、容错等,实现服务发现与注册
-
服务注册
- Eureka采用了CS的设计架构,Eureka Server 作为服务注册功能的服务器,它是服务注册中心,而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员可以通过Eureka Server来监控系统中各个微服务是否正常运行
- 在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器信息(如服务地址通信地址等)以别名的方式注册到注册中心。另一方(消费者服务提供者),以该别名的方式注册中心上获取实际的通信地址,然后再实现本地RPC调用RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一种依赖关系(服务治理概念)。在任何rpc远程调用,都会有一个注册中心(存放服务地址相关信息(接口地址))
- Eureka包含两个组件:Eureka Server 和 Eureka Client
- Eureka Server提供服务注册服务,各个微服务节点通过配置启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到
- Eureka Client 通过注册中心进行访问,是一个java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的,使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会想Eureka Server 发送心跳(默认周期30s)。如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureak Server将会从服务注册表中把这个服务节点移除(默认90s)
5.2、单机Eureka构建步骤
- 创建 cloud-eureka-server7001服务
- maven依赖
<dependencies>
<!--eureka server-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--引入自己定义的api通用包-->
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--boot web actuator-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--一般通用配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
- application.yml
server:
port: 7001
eureka:
instance:
hostname: localhost # eureka服务端的实例名称
client:
register-with-eureka: false # false 表示不向注册中心注册自己
fetch-registry: false # false 是否从Eureka Server 抓取已有的注册信息
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
-
在启动类上添加 EnableEurekaServer 注解,服务端
-
localhost:7001访问Eureka Server
-
将provider-8001注册到Eureka Server
-
添加Eureka Client依赖
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
- 在application.yml添加Eureka Client配置信息
eureka:
client:
register-with-eureka: true # ture 自己注册到 Eureka Server
fetch-registry: true # 是否从Eureka Server 抓取已有的注册信息
service-url:
defaultZone: http://localhost:7001/eureka
-
在启动类上添加 @EnableEurekaClient 注解,客户端
-
访问Eureka Server
- 使用同样的步骤将comsumer-80服务注册到Eureka Server
5.3、Eureka集群
- 在C:\Windows\System32\drivers\etc下hosts文件中添加地址映射
127.0.0.1 eureka7001.com
127.0.0.1 eureka7002.com
- 修改 eureka7001、eureka7002的配置文件,让两个Eureka Server相互注册
- eureka7001
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com # eureka服务端的实例名称
client:
register-with-eureka: false # false 表示不向注册中心注册自己
fetch-registry: false # false 表示自己就是注册中心
service-url:
defaultZone: http://eureka7002.com:7002/eureka # 注册到 EurekaServer 7002
- eureka7002
server:
port: 7002
eureka:
instance:
hostname: eureka7002.com # eureka服务端的实例名称
client:
register-with-eureka: false # false 表示不向注册中心注册自己
fetch-registry: false # false 表示自己就是注册中心
service-url:
defaultZone: http://eureka7001.com:7001/eureka # 注册到 EurekaServer 7001
- 访问 7001Eureka服务
- 访问 7002Eureka服务
- 修改provider-8001 和 consumer-80 两个服务的配置文件,将两个服务分别注册到Eureka7001,和Eureka7002
eureka:
client:
register-with-eureka: true # ture 自己注册到 Eureka Server
fetch-registry: true # 是否从Eureka Server 抓取已有的注册信息
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
5.4、provider集群配置
-
新建项目 cloud-provider-payment8002
-
provider8002和provider8001除了端口号不同其他一样的配置
- 在consuemr80的配置类RestTemplate对象上添加 @LoadBalanced 注解,赋予RestTemplate负载均衡能力
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡能力
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
- 将consumer80服务controller中提供者的url地址改为提供者的服务名称
//提供者provider的url地址
//public static final String PAYMENT_URL = "http://localhost:8001";
public static final String PAYMENT_URL = "http://CLOUD-PAYMENT-SERVICE";
5.5、actuator微服务信息完善
- 修改服务名称
- 访问信息有ip显示
eureka:
client:
register-with-eureka: true # ture 自己注册到 Eureka Server
fetch-registry: true # 是否从Eureka Server 抓取已有的注册信息
service-url:
defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
instance:
instance-id: privider8001 # 修改服务名称
prefer-ip-address: true # 访问信息ip地址
5.6、服务发现Discovery
- 对于注册进Eureka里面的微服务,可以通过服务发现来获得该服务的信息
- 修改provider8001的Controller
@RestController
@Slf4j
public class PaymentController {
//服务发现
@Autowired
private EurekaDiscoveryClient discoveryClient;
//获取Eureka中的服务信息
@GetMapping("/payment/discovery")
public Object discovery(){
//Eureka中的 Application
List<String> services = discoveryClient.getServices();
for (String element:services){
log.info("======>"+element);
}
//指定Application下的具体信息
List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD-PAYMENT-SERVICE");
for (ServiceInstance instance:instances){
log.info(instance.getServiceId()+" "+instance.getHost()+" "+instance.getPort()+" "+ instance.getUri());
}
return this.discoveryClient;
}
}
- 在启动类添加 @EnableDiscoveryClient 注解,开启Euerka服务发现功能
@SpringBootApplication
@EnableEurekaClient //Eureka Client
@EnableDiscoveryClient //开启 Eureka 服务发现功能
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class,args);
}
}
- 控制台输出
# Eureka中的 Application
======>cloud-payment-service
======>cloud-order-service
# CLOUD-PAYMENT-SERVICE 的具体信息
CLOUD-PAYMENT-SERVICE 172.25.152.61 8002 http://172.25.152.61:8002
CLOUD-PAYMENT-SERVICE 172.25.152.61 8001 http://172.25.152.61:8001
5.7、Eureka自我保护
- 保护模式主要用于客户端和Eureka Server之间存在网络分区场景下的保护,一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据,也就是不会注销任何微服务
- 某时刻某一微服务不可用了,Eureka不会立刻清理,依旧会对该微服务的信息进行保存
-
禁止自我保护
-
Eureka Server 7001
server:
port: 7001
eureka:
instance:
hostname: eureka7001.com # eureka服务端的实例名称
client:
register-with-eureka: false # false 表示不向注册中心注册自己
fetch-registry: false # false 表示自己就是注册中心
service-url:
defaultZone: http://eureka7001.com:7001/eureka
# defaultZone: http://eureka7002.com:7002/eureka # 注册到 EurekaServer 7002
server:
enable-self-preservation: false # 关闭自我保护机制
eviction-interval-timer-in-ms: 2000 # 清理无效服务的时间间隔
- Eureka Client 8001
eureka:
client:
register-with-eureka: true # ture 自己注册到 Eureka Server
fetch-registry: true # 是否从Eureka Server 抓取已有的注册信息
service-url:
# defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka
defaultZone: http://eureka7001.com:7001/eureka
instance:
instance-id: privider8001 # 修改服务名称
prefer-ip-address: true # 访问信息ip地址
lease-renewal-interval-in-seconds: 1 # Eureka客户端向服务端发送心跳的时间间隔 默认30s
lease-expiration-duration-in-seconds: 2 # Eureka服务端在收到最后一次心跳后等待时间上限,默认90s,超时将剔除服务
6、Zookeeper服务注册和发现
6.1、docker安装zookeeper
- 拉取镜像
docker pull zookeeper:3.4.9
- 运行zookeeper
docker run -d -p 2181:2181 zookeeper:3.4.9
- 进入zookeeper客户端
docker exec -it 3465b21f6fa6 zkCli.sh
6.2、provider-8004服务注册到zookeeper
- 新建项目 cloud-provider-payment8004
- maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<!--排除start中包含的zookeeper-->
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--使用和服务器安装的zookeeper一样的版本-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- application.yml配置文件
server:
port: 8004
spring:
application:
name: cloud-provider-payment
cloud:
zookeeper:
connect-string: 82.156.13.249:2181 # zookeeper服务IP地址和端口号
- 启动类 添加 @EnableDiscoveryClient 服务发现注解
@SpringBootApplication
@EnableDiscoveryClient //服务发现
public class PaymentMain8004 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8004.class,args);
}
}
- controller
@RestController
@Log4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/zk")
public String paymentZK(){
return "springCloud with zookeeper:"+serverPort;
}
}
-
启动provider-8004服务
-
在zookeeper中查看服务信息
6.3、consumer-81注册到zookeeper
- maven依赖和provider-8004一样
- application.yml
server:
port: 81
spring:
application:
name: cloud-consumer-order
cloud:
zookeeper:
connect-string: 82.156.13.249:2181 # zookeeper服务IP地址和端口号
- 配置类,注入RestTemplate
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡能力
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
- 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class OrderMain81 {
public static void main(String[] args) {
SpringApplication.run(OrderMain81.class,args);
}
}
- controller,调用provider-8004服务
@RestController
public class OrderZKController {
public static final String INVOKE_URL = "http://cloud-provider-payment";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/zk")
public String paymentInfo(){
String res = restTemplate.getForObject(INVOKE_URL+"/payment/zk",String.class);
return res;
}
}
- 启动consumer81
[zk: localhost:2181(CONNECTED) 20] ls /services
[cloud-provider-payment, cloud-consumer-order]
- 同过conmer-81调用provider-8004获取数据
7、Consul服务注册和发现
7.1、Consul简介
- Consul是一套开源的分布式服务发现和配置管理系统,由HashiCorp公司用Go语言开发
- 提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建全方位的服务网格。
- 它具有很多优点,包括:基于raft协议,比较简洁;支持健康检查,同时支持HTTP和DNS协议 支持跨数据中心的 WAN 集群 提供图形界面 跨平台,支持linux mac windows
7.2、docker安装consul
- 拉取镜像
docker pull consul:1.6.1
- 运行consul
docker run -d -p 8500:8500 consul:1.6.1
- 访问consul图形界面
7.3、provider-8006服务注册到consul
- maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.atguigu</groupId>
<artifactId>cloud-api-commons</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
- application.yml
server:
port: 8006
spring:
application:
name: consul-provider-payment
cloud:
consul:
host: 82.156.13.249
port: 8500
discovery:
hostname: 82.156.13.249
service-name: ${spring.application.name}
heartbeat:
enabled: true
prefer-ip-address: true
- 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class PaymentMain8006 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8006.class,args);
}
}
- controller
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String serverPort;
@GetMapping("/payment/consul")
public String paymentConsul(){
return "spring cloud with consul" + serverPort;
}
}
- 访问consul图形化界面
7.4、consumer-83服务注册到consul
- maven依赖和provider-8006一样
- application.yml
server:
port: 83
spring:
application:
name: cloud-consumer-order
cloud:
consul:
host: 82.156.13.249
port: 8500
discovery:
hostname: 82.156.13.249
service-name: ${spring.application.name}
heartbeat:
enabled: true
prefer-ip-address: true
- 启动类
@SpringBootApplication
@EnableDiscoveryClient
public class OrderMain83 {
public static void main(String[] args) {
SpringApplication.run(OrderMain83.class,args);
}
}
- 配置类,注入RestTemplate
@Configuration
public class ApplicationContextConfig {
@Bean
@LoadBalanced //使用@LoadBalanced注解赋予RestTemplate负载均衡能力
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
- controller
@RestController
public class OrderConsulController {
private String INVOKE_URL = "http://consul-provider-payment";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/payment/consul")
public String payment(){
String res = restTemplate.getForObject(INVOKE_URL + "/payment/consul", String.class);
return res;
}
}
- 启动consumer-83服务
- 通过consumer-83服务调用provider8006服务
8、三个注册中心异同点
组件名 | 语言 | CAP | 服务健康检查 | 对外暴露接口 | Spring Cloud集成 |
---|---|---|---|---|---|
Eureka | Java | AP | 可配支持 | HTTP | 已集成 |
Consul | Go | CP | 支持 | HTTP | DNS |
Zookeeper | Java | CP | 支持 | 客户端 | 已集成 |
- CPA理论的核心是:一个分布式系统不可能同时很好的满足一致性,可用性和分区容错性这三个需求
- CA-单点集群,满足一致性,可用性的系统,通常在可扩展性上不太强大
- CP-满足一致性,分区容错性的系统,通常新能不是特别高
- AP-满足可用性,分区容错性的系统,通常对一致性要求低一些