使用Consul提供注册和发现服务

什么是 Consul

Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置。与其它分布式服务注册与发现的方案,Consul 的方案更“一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value 存储、多数据中心方案,不再需要依赖其它工具(比如 ZooKeeper 等)。使用起来也较为简单。Consul 使用 Go 语言编写,因此具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与 Docker 等轻量级容器可无缝配合。

Consul 安装

访问 Consul 官网 ,根据操作系统类型,选择下载 Consul 的最新版本。我这里选择windows版本。

下载下来是一个zip压缩包,解压之后,是一个exe可执行文件。

打开CMD终端,进入consul.exe所在目录,执行如下命令启动Consul服务。

cd C:\consul_1.3.0_windows_amd64  # 进入consul.exe所在目录
consul agent -dev # 启动服务, -dev 表示开发模式运行,另外还有 -server 表示服务模式运行

启动过程信息如下图所示。

启动成功之后,访问 http://localhost:8500 , 可以查看 Consul 管理界面。

Consul 服务提供者

服务注册发现中心有了,现在我们来开发服务提供者。

新建项目 spring-cloud-consul-producer,添加以下依赖。

pom.xml

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

说明:

spring-boot-starter-actuator 健康检查依赖于此包。

spring-cloud-starter-consul-discovery Spring Cloud Consul 的支持。

注意添加Spring Cloud的依赖配置,完整内容参见源码pom文件。

  <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>

添加配置

在配置文件添加内容如下。

application.yml

server:
port: 8511
spring:
application:
name: spring-cloud-consul-producer
cloud:
consul:
host: localhost
port: 8500
discovery:
serviceName: service-producer # 注册到consul的服务名称

Consul 的地址和端口号默认是 localhost:8500 ,如果不是这个地址可以自行配置,consul服务会占用8502接口,所以不要用8501、8502。
spring.cloud.consul.discovery.serviceName 是指注册到 Consul 的服务名称,后期客户端会根据这个名称来进行服务调用。

修改启动类

修改启动器类,添加 @EnableDiscoveryClient 注解,开启服务发现支持。

package com.louis.spring.cloud.consul.producer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; @EnableDiscoveryClient
@SpringBootApplication
public class ConsuleProducerApplication { public static void main(String[] args) {
SpringApplication.run(ConsuleProducerApplication.class, args);
}
}

添加服务

新建 HelloController,提供 hello 接口, 返回 hello consul 字符串。

package com.louis.spring.cloud.consul.producer.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class HelloController { @RequestMapping("/hello")
public String hello() {
return "hello consul.";
}
}

为了模拟注册均衡负载,复制一份上面的项目,重命名为 spring-cloud-consul-producer2 ,修改对应的端口为 8512,修改 hello 方法的返回值为:"helle consul two",修改完成后依次启动两个项目,启动成功之后刷新Consul管理界面,发现我们注册的service-producer服务,并有2个节点实例。

点击进入节点详情页面,可以看到我们注册的8511和8512两个服务提供者节点实例。

Consul 消费者

服务注册发现中心有了,服务提供者也有了,现在我们来开发服务消费者。

新建项目 spring-cloud-consul-comsumer,依赖同提供者。

添加配置

修改配置文件如下。

application.yml

server:
port: 8521
spring:
application:
name: spring-cloud-consul-consumer
cloud:
consul:
host: localhost
port: 8500
discovery:
register: false #设置不需要注册到 consul 中

客户端可以设置是否注册到 Consul 中,具体需要根据我们的业务来选择,一般在需要对外提供服务时进行注册。

启动器类

ConsuleConsumerApplication.java

package com.louis.spring.cloud.consul.producer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class ConsuleConsumerApplication { public static void main(String[] args) {
SpringApplication.run(ConsuleConsumerApplication.class, args);
}
}

服务消费者

添加消费服务测试类,添加两个接口,一个查询所有我们注册的服务,另一个从我们注册的服务中选取一个服务,采用轮询的方式。

ServiceController.java

package com.louis.spring.cloud.consul.producer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; @RestController
public class ServiceController { @Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private DiscoveryClient discoveryClient; /**
* 获取所有服务
*/
@RequestMapping("/services")
public Object services() {
return discoveryClient.getInstances("service-producer");
} /**
* 从所有服务中选择一个服务(轮询)
*/
@RequestMapping("/discover")
public Object discover() {
return loadBalancerClient.choose("service-producer").getUri().toString();
}
}

添加完成之后,启动项目, 访问 http://localhost:8521/services,返回两个服务,分别是我们注册的8511和8512。

[{
"serviceId": "service-producer",
"host": "GG20J1G2E.logon.ds.ge.com",
"port": 8511,
"secure": false,
"metadata": {
"secure": "false"
},
"uri": "http://GG20J1G2E.logon.ds.ge.com:8511",
"scheme": null
}, {
"serviceId": "service-producer",
"host": "GG20J1G2E.logon.ds.ge.com",
"port": 8512,
"secure": false,
"metadata": {
"secure": "false"
},
"uri": "http://GG20J1G2E.logon.ds.ge.com:8512",
"scheme": null
}]

反复访问 http://localhost:8521/discover,结果交替返回服务8511和8512,因为默认的负载均衡器是采用轮询的方式。

http://GG20J1G2E.logon.ds.ge.com:8511
http://GG20J1G2E.logon.ds.ge.com:8512
...

8511 和 8512 两个服务会交替出现,从而实现了获取服务端地址的均衡负载。

大多数情况下我们希望使用均衡负载的形式去获取服务端提供的服务,因此使用第二种方法来模拟调用服务端提供的 hello 方法。

创建 CallHelloController.java

package com.louis.spring.cloud.consul.producer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; @RestController
public class CallHelloController { @Autowired
private LoadBalancerClient loadBalancer; @RequestMapping("/call")
public String call() {
ServiceInstance serviceInstance = loadBalancer.choose("service-producer");
System.out.println("服务地址:" + serviceInstance.getUri());
System.out.println("服务名称:" + serviceInstance.getServiceId()); String callServiceResult = new RestTemplate().getForObject(serviceInstance.getUri().toString() + "/hello", String.class);
System.out.println(callServiceResult);
return callServiceResult;
} }

使用 RestTemplate 进行远程调用。添加完之后重启 spring-cloud-consul-consumer 项目。

在浏览器中访问地址:http://localhost:8521/call,依次返回结果如下:

helle consul
helle consul two
...

服务注册和发现(Consul)的更多相关文章

  1. 分布式服务注册和发现consul 简要介绍

    Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其他分布式服务注册与发现的方案,Consul的方案更"一站式",内置了服务注册与发现框 架 ...

  2. 微服务之服务注册与发现--Consul(转载)

    http://blog.csdn.net/buxiaoxia/article/details/69788114 https://www.cnblogs.com/xiaohanlin/p/8016803 ...

  3. 5.服务注册与发现Consul,简学API,手动注册和删除服务

    package main import ( httptransport "github.com/go-kit/kit/transport/http" mymux "git ...

  4. C#使用Consul集群进行服务注册与发现

    前言 我个人觉得,中间件的部署与使用是非常难记忆的:也就是说,如果两次使用中间件的时间间隔比较长,那基本上等于要重新学习使用. 所以,我觉得学习中间件的文章,越详细越好:因为,这对作者而言也是一份珍贵 ...

  5. 温故知新,.Net Core遇见Consul(HashiCorp),实践分布式服务注册与发现

    什么是Consul 参考 https://www.consul.io https://www.hashicorp.com 使用Consul做服务发现的若干姿势 ASP.NET Core 发布之后通过命 ...

  6. Spring Cloud Consul 实现服务注册和发现

    Spring Cloud 是一个基于 Spring Boot 实现的云应用开发工具,它为基于 JVM 的云应用开发中涉及的配置管理.服务发现.断路器.智能路由.微代理.控制总线.全局锁.决策竞选.分布 ...

  7. 基于 Consul 实现 MagicOnion(GRpc) 服务注册与发现

    0.简介 0.1 什么是 Consul Consul是HashiCorp公司推出的开源工具,用于实现分布式系统的服务发现与配置. 这里所谓的服务,不仅仅包括常用的 Api 这些服务,也包括软件开发过程 ...

  8. Docker+Consul+Registrator 实现服务注册与发现

    Docker+Consul+Registrator实现服务注册与发现 逻辑图 实现nginx节点自动化加入容器IP代理 1.三台Consul agent server作为高可用通过Consul Tem ...

  9. Spring Boot + Spring Cloud 构建微服务系统(一):服务注册和发现(Consul)

    使用Consul提供注册和发现服务 什么是 Consul Consul 是 HashiCorp 公司推出的开源工具,用于实现分布式系统的服务发现与配置.与其它分布式服务注册与发现的方案,Consul ...

随机推荐

  1. 大话WebRTC的前世今生

    音视频的历史 音视频可以说是人类与生俱来的需求,人一出生就要用耳朵听,用眼睛看.中国的古代神话中为此还专门设置了两位神仙(千里眼和顺风耳),他们可以听到或看到千里之外的声音或景像. 为了解决听的远和看 ...

  2. leecode第七十八题(子集)

    class Solution { public: vector<vector<int>> subsets(vector<int>& nums) { vect ...

  3. RNN生产唐诗

    1. 项目的RNN模型: 项目中的输入x是这样的:

  4. VNPY思维导图架构

    VNPY是使用人数世界第三,国内第一的量化交易框架,封装的接口主要有ctp(期货),wind,xtp(股票)等.内部包含回测.实盘.模拟盘等模块.数据库默认为MongoDB的no-sql数据库,基于p ...

  5. C# DataTable 通过Linq分组

    datatable我们是经常使用到的,但是需要对数据进行分组,具体代码如下: var result = dt.AsEnumerable().GroupBy(f => new { type = f ...

  6. 雷林鹏分享:jQuery EasyUI 树形菜单 - 树形网格动态加载

    jQuery EasyUI 树形菜单 - 树形网格动态加载 动态加载树形网格有助于从服务器上加载部分的行数据,避免加载大型数据的长时间等待.本教程将向您展示如何创建带有动态加载特性的树形网格(Tree ...

  7. spring ----> aop的两种实现方式

    实现1:基于xml package com.rr.spring3.interf; //接口 public interface SayHello { public void sayHello(); } ...

  8. 【debug、info、warn、error】四者之间的区别与用法

    debug:需要在调试过程中输出的信息,但发布后是不需要的(当然发布后,也是看不到的) info:需要持续输出的信息(无论调试还是发布状态) warn:警告级别的信息(不严重) error:错误信息( ...

  9. display:inline-block与float

    display:inline-block 既有行级元素的特性,也有块级元素的特性,因此在同一行,能设置宽高,margin,padding inline-block和float的区别 虽然设置float ...

  10. DVWA-CSRF

    Low等级   image 抓包   image 正常跳转   image   image 在这里我们把密码改为qwer   image   image   image   image   image ...