SpringBoot系列: 使用 consul 作为服务注册组件
本文基本上摘自纯洁的微笑的博客 http://www.ityouknow.com/springcloud/2018/07/20/spring-cloud-consul.html . 感谢作者的付出.
=============================
服务注册基础组件选择
=============================
在服务注册这个环节, 业界有很多组件可供选择, 主要有:
1. Spring Cloud Eureka
Spring Cloud Eureka 是 Spring Cloud Netflix 项目下的服务治理模块, 而 Sping Cloud Netflix 是 Spring Cloud 的子项目之一, 主要是对 Netflix 公司开源的一些产品的封装, 这包括, 服务发现 (Eureka), 智能路由 (Zuul), 客户端负载均衡 (Ribbon), 断路器 (Hystrix).
2. Consul
Consul 主要用于服务注册, 分布式配置管理等领域, 对于服务注册方面它是一个一站式的解决方案, 提供健康检查, DNS 域名解析等功能. Spring Cloud 也有基于 consul 的服务治理子项目 Spring Cloud Consul, 主要提供服务注册和分布式配置管理功能.
3. Zookeeper
Zookeeper 也是一个流行的开源项目, 主要用于分布式事务协调, 服务注册, 分布式配置管理等领域. Spring Cloud 也有基于 zookeeper 的服务治理子项目 Spring Cloud Zookeeper, 主要提供服务注册和分布式配置管理功能.
我的推荐: Consul + Spring Cloud Consul. 原因有:
1. Consul 胜出 Eureka 的地方: Consul 更知名, 更流行, Consul 集群运维成本自然低了不少.
2. Consul 胜出 Zookeeper 的地方: ZooKeeper 的知名度要比 Consul 高, 但 Consul 在流行程度上也不会差很多. 回到服务注册这个领域, Consul 比 ZooKeeper 更加全面更完善, 健康检查和 DNS 服务是拿来即用的.
=============================
Demo 整体设计 和 Consul 启动
=============================
服务生产者项目将向 consul 注册自己, 另一个项目是服务消费者. 整个架构包括:
1. 服务生产者项目部署两份, 这样能提供要给 HA
2. 服务消费者项目, 服务消费者能自动应用负载均衡策略向两个生产者服务发出请求.
3. consul 的作用, 不管是 HA 还是 LB, 都是需要 consul 提供的 DNS 支持.
服务生产者项目的要点:
1. 主程序加上 @EnableDiscoveryClient 注解
在消费项目主要用到了下面 3 个接口/类:
1. DiscoveryClient 接口, 用于服务发现操作, 自动注入的实际类型为 CompositeDiscoveryClient 类.
2. LoadBalancerClient 接口, 用于负载均衡,自动注入的实际类型为 RibbonLoadBalancerClient 类.
3. RestTemplate 类, 用于进行 http 请求, 有两种方式实现负载均衡. 一个方法是在发出web请求的时候, 传入 LoadBalancerClient.getServiceId() url; 另一个方法是直接创建一个负载均衡的 RestTemplate实例, web 请求的 url 格式就可以泛化为 http://service-producer/your_api .
=============================
Consul 启动
=============================
consul server 直接使用 consul agent --dev 命令, 启动一个测试 server 即可, 得到两个重要的访问端口.
输出有:
Started DNS server 127.0.0.1:8600 (tcp)
Started HTTP server on 127.0.0.1:8500 (tcp)
=============================
spring-cloud-starter-consul-discovery 一些重要属性
=============================
# 直接指定服务的 consul service id(即 instance id).
# 默认情况下为 spring.application.name + server.port, 如果在多个服务器上同一个服务, 因为应用名和端口都一致, 会导致service id 会重复, 所以一般情况都需要引入一个随机数避免重复 .
spring.cloud.consul.discovery.instance-id=${spring.application.name}-${random.value} # 指定服务的 consul service name
spring.cloud.consul.discovery.service_name=some_name # consul 服务器主机名
spring.cloud.consul.discovery.hostname=your_host # consul 服务器端口
spring.cloud.consul.discovery.port= # 维护 tags
$ 下面示例的 tag map 是: foo->bar 和 baz->baz
spring.cloud.consul.discovery.tags:foo=bar, baz # 是否启用服务发现
spring.cloud.consul.discovery.enabled=true # 使用 consul 服务器 IP, 而不是 hostname, 需要搭配 prefer-ip-address 属性
spring.cloud.consul.discovery.ip-address=127.0.0.1 # 在注册时使用 consul IP, 而不是 hostname
spring.cloud.consul.discovery.prefer-ip-address=false #设定 consul acl token 值
spring.cloud.consul.discovery.acl-token=4efb1523-76a3-f476-e6d8- # 健康检查的频率, 默认 秒
spring.cloud.consul.discovery.health-check-interval=10s # actuator 健康检查的 url 路径
# 默认为 为${management.endpoints.web.base-path} +/health
spring.cloud.consul.discovery.health-check-path= # 自定义健康检查的 url(适合于不适用 actuator 的场景)
spring.cloud.consul.discovery.health-check-url=
=============================
服务生产者项目 1
=============================
一个简单的 Restful Service 项目.
----------------------------
pom.xml
----------------------------
项目使用 spring starter 向导生成, 增加 actuator 和 consul-discovery 依赖.
1. actuator 是必需的, 用于 consul 监控 web 项目的健康状态.
2. spring-cloud-starter-consul-discovery 也是必需的, Consul 服务发现的 starter jar 包.
pom.xml 重要内容有:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
</dependencies> <dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
----------------------------
主入口程序 SvcProducerApplication
----------------------------
在主入口程序类上增加 @EnableDiscoveryClient 注解后, 自动完成服务注册.
@SpringBootApplication
@EnableDiscoveryClient
public class SvcProducerApplication {
public static void main(String[] args) {
SpringApplication.run(SvcProducerApplication.class, args);
}
}
----------------------------
Rest 服务类 HelloController
----------------------------
很简单的一个服务类, 提供一个 Restful API.
public class HelloController {
private String port="8080" ;
@RequestMapping("/hello")
public String hello() {
return "hello consul from "+this.port;
}
}
----------------------------
application.properties 文件
----------------------------
设定 consul 的 http 注册 IP 和端口 (8500), 并设定 consul service id 和 consul service name.
consul service id 是必需的, 生成的规则: spring.application.name+[-[server.port]]
consul service name 不是必需的, 但往往需要配置. 设定属性为: spring.cloud.consul.discovery.serviceName, 不设定的话, name 值同 Id 值.
consul service name 和 consul service id 的简单类比, consul service name 相当于 DNS 的域名, id 相当于 DNS A 记录.
文件的内容:
spring.application.name=spring-cloud-consul-producer
server.port=
spring.cloud.consul.discovery.serviceName=service-producer
spring.cloud.consul.host=localhost
spring.cloud.consul.port=
启动后将有下面的服务注册日志:
Registering service with consul: NewService{id='spring-cloud-consul-producer-8080', name='service-producer', tags=[secure=false], address='admin-PC', port=8080, enableTagOverride=null, check=Check{script='null', interval='10s', ttl='null', http='http://admin-PC:8080/actuator/health', tcp='null', timeout='null', deregisterCriticalServiceAfter='null', tlsSkipVerify=null, status='null'}, checks=null}
=============================
服务生产者项目 2
=============================
服务生产者项目 2 和项目 1 其实应该完全一致, 因为我们想要在一台电脑上部署, 所以修改一下对应端口即可.
=============================
服务消费者项目
=============================
----------------------------
pom.xml
----------------------------
pom.xml 同 服务生产者项目. 需要说明的是:
1. actuator 对于服务消费者来讲, 并不是必需的.
2. spring-cloud-starter-consul-discovery 是必需的, Consul 服务发现的 starter jar 包.
----------------------------
application.properties 文件
----------------------------
只需要指定 consul 的服务 hostname 和端口即可.
spring.application.name=spring-cloud-consul-consumer
server.port=
spring.cloud.consul.host=127.0.0.1
spring.cloud.consul.port=
----------------------------
消费类文件 ServiceController.java
----------------------------
在消费代码中, 主要用到了下面 3 个接口/类:
1. DiscoveryClient 接口, 用于服务发现操作, 自动注入的实际类型为 CompositeDiscoveryClient 类.
2. LoadBalancerClient 接口, 用于负载均衡,自动注入的实际类型为 RibbonLoadBalancerClient 类.
3. RestTemplate 类, 用于进行 http 请求, 有两种方式实现负载均衡. 一个方法是在发出web请求的时候, 传入 LoadBalancerClient.getServiceId() url; 另一个方法是直接创建一个负载均衡的 RestTemplate实例, web 请求的 url 格式就可以泛化为 http://service-producer/your_api .
@RestController
public class ServiceController {
@Autowired
private LoadBalancerClient loadBalanacer;
@Autowired
private DiscoveryClient discoverClient; /**
* 获取所有的服务
*/
@RequestMapping("/services")
public Object services() {
return discoverClient.getInstances("service-producer");
} @RequestMapping("/discover")
public Object discover() {
return loadBalanacer.choose("service-producer").getUri().toString();
}
} @RestController
class HelloController {
@Autowired
private LoadBalancerClient loadBalancer; /*
* 声明一个负载均衡的 RestTemplate bean
* */
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
} /*
* 自动注入一个负载均衡的 RestTemplate
* */
@Autowired
private RestTemplate restTemplate; @RequestMapping("/call")
public String call() {
ServiceInstance serviceInstance = loadBalancer.choose("service-producer");
System.out.println("Hostname:" + serviceInstance.getUri());
System.out.println("service name:" + serviceInstance.getServiceId()); //String serviceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello",String.class);
String serviceResult=restTemplate.getForObject("http://service-producer/hello",String.class);
return serviceResult ;
}
}
=============================
参考
=============================
springcloud(十三):注册中心 Consul 使用详解
http://www.ityouknow.com/springcloud/2018/07/20/spring-cloud-consul.html
https://www.cnblogs.com/ityouknow/p/9340591.html
Spring Cloud Finchley 版中 Consul 多实例注册的问题处理
http://blog.didispace.com/Spring-Cloud-Finchley-Consul-InstanceId/
Spring Cloud 构建微服务架构:服务注册与发现(Eureka、Consul)【Dalston 版】
http://blog.didispace.com/spring-cloud-starter-dalston-1/
https://howtodoinjava.com/spring-cloud/consul-service-registration-discovery/
使用 Spring Cloud Consul 实现服务的注册和发现
https://blog.csdn.net/mn960mn/article/details/51775212
Spring Cloud(二) Consul 服务治理实现
https://segmentfault.com/a/1190000012245512
SpringBoot系列: 使用 consul 作为服务注册组件的更多相关文章
- Spring Cloud Consul 实现服务注册和发现
Spring Cloud 是一个基于 Spring Boot 实现的云应用开发工具,它为基于 JVM 的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布 ...
- SpringBoot系列: 如何优雅停止服务
============================背景============================在系统生命周期中, 免不了要做升级部署, 对于关键服务, 我们应该能做到不停服务完成 ...
- .net core grpc consul 实现服务注册 服务发现 负载均衡(二)
在上一篇 .net core grpc 实现通信(一) 中,我们实现的grpc通信在.net core中的可行性,但要在微服务中真正使用,还缺少 服务注册,服务发现及负载均衡等,本篇我们将在 .net ...
- .netcore consul实现服务注册与发现-集群完整版
原文:.netcore consul实现服务注册与发现-集群完整版 一.Consul的集群介绍 Consul Agent有两种运行模式:Server和Client.这里的Server和Clien ...
- 服务注册组件——Eureka高可用集群搭建
服务注册组件--Eureka高可用集群搭建 什么是Eureka? 服务注册组件:将微服务注册到Eureka中. 为什么需要服务注册? 微服务开发重点在一个"微"字,大型应用拆分成微 ...
- .netcore consul实现服务注册与发现-集群部署
一.Consul的集群介绍 Consul Agent有两种运行模式:Server和Client.这里的Server和Client只是Consul集群层面的区分,与搭建在Cluster之上的应用服务无关 ...
- .Net Core Grpc Consul 实现服务注册 服务发现 负载均衡
本文是基于..net core grpc consul 实现服务注册 服务发现 负载均衡(二)的,很多内容是直接复制过来的,..net core grpc consul 实现服务注册 服务发现 负载均 ...
- .netcore consul实现服务注册与发现-单节点部署
原文:.netcore consul实现服务注册与发现-单节点部署 一.Consul的基础介绍 Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分 ...
- Dubbo 微服务系列(03)服务注册
Dubbo 微服务系列(03)服务注册 [TOC] Spring Cloud Alibaba 系列目录 - Dubbo 篇 1. 背景介绍 图1 Dubbo经典架构图 注:本图来源 Dubbo官方架构 ...
随机推荐
- PyCharm使用小技巧
本文部分内容参考了明宇李前辈的博客,原文请阅读 Pycharm的配置(背景颜色,字体,解释器等): 鼠标滑轮控制字体大小 部分参考了墨颜前辈的博客,原文请阅读 用鼠标滑轮控制代码字体大小: 感谢各位前 ...
- Python基础——1基础
1.基础 输出 print(‘把子肉爱上热干面’,‘哈哈’) # ‘,’输出为空格 输人 name = input(‘提示的内容’) /浮点除法 %.6f //地板除法 整除 % 取余 pyt ...
- Linux Collection:网络配置
PAS 缺少ifconfig 安装相应软件[不推荐],尽量使用 ip 命令 sudo apt install gnome-nettool 补充,显示IP地址: ip show address PAS ...
- [经验总结] 从其它sheet页引用数据生成图表时没有图例的解决办法
1.先给出一个在有数据区域的sheet页中生成的图表,比较全,图表和图例全部都有,如下图: 2.但是如果在其它 sheet页中引用该有数据的sheet数据时并生成图表,生成的图表只有图表区域显示,图例 ...
- virtualenvwrapper 虚拟环境的使用 和 python 安装源的更改
virtualenvwrapper 虚拟环境的使用 鉴于virtualenv不便于对虚拟环境集中管理,所以推荐直接使用virtualenvwrapper. virtualenvwrapper提供了一系 ...
- java.io.IOException: There appears to be a gap in the edit log. We expected txid ***, but got txid
方式1 原因:namenode元数据被破坏,需要修复解决:恢复一下namenode hadoop namenode -recover 一路选择Y,一般就OK了 方式2 Need to copy the ...
- audio元素和video元素在ios和andriod中无法自动播放
原因: 因为各大浏览器都为了节省流量,做出了优化,在用户没有行为动作时(交互)不予许自动播放: /音频,写法一 <audio src="music/bg.mp3" autop ...
- @getMapping与@postMapping
首先要了解一下@RequestMapping注解. @RequestMapping用于映射url到控制器类的一个特定处理程序方法.可用于方法或者类上面.也就是可以通过url找到对应的方法. @Requ ...
- day 13 迭代器、可迭代对象、迭代器对象、生成器、生成器对象、枚举对象
迭代器大概念 # 迭代器:循环反馈的容器(集合类型)# -- 不同于索引取值,但也可以循环的从容器对象中从前往后逐个返回内部的值# 优点:不依赖索引,完成取值# 缺点:不能计算长度,不能指定位取值( ...
- jenkins的安装部署
jenkins安装 参考连接: https://wiki.jenkins.io/display/JENKINS/Installing+Jenkins+on+Red+Hat+distributions ...