您当前的位置: 首页 >  蔚1 spring cloud

Spring Cloud 与 Consul 的整合使用

蔚1 发布时间:2019-04-02 23:30:17 ,浏览量:2

Spring Cloud 热度日益提升,注册中心、配置中心的选型是一个必然面对的问题。Eureka 2.0 开源工作宣告停止,Zookeeper 略显笨重,Consul 是某种业务场景下相对较好的选择。Consul 部署简单,兼具注册中心和配置中心,Go 语言带来的高效,可集群部署实现高可用,是 Spring Cloud 的较好搭配。

本场 Chat 将与大家分享 Spring Cloud 选择 Consul 作为注册中心和配置中心的整合过程,与大家分享将 Consul 作为 Spring Cloud 注册中心和配置中心的应用实践及感悟。适合有意向或正在使用 Consul 作为 Spring Cloud 配套的 Java 开发人员。

本场 Chat 你讲学到如下内容:

  1. 了解 Spring Cloud 采用 Consul 作为注册中心该如何实现。
  2. 了解 Spring Cloud 采用 Consul 作为配置中心该如何实现。
Spring Cloud 与 Consul 的整合使用 1. 背景

Spring Cloud 热度日益提升,注册中心、配置中心的选型是一个必然面对的问题。 Eureka 2.0 开源工作宣告停止,Zookeeper 略显笨重,相比之下,Consul 就是很多业务场景下较好的选择。Consul 部署简单,兼具注册中心和配置中心,Go 语言带来了高效,可集群部署能实现高可用,综合来看是 Spring Cloud 的较好搭配。

本场 Chat 中,作者将与大家分享 Spring Cloud 选择 Consul 作为注册中心和配置中心的整合过程,并结合实例分享应用实践及感悟。

适合有意向或正在使用 Consul 作为 Spring Cloud 配套的 Java 开发人员。

通过本场 Chat 你将学了解到如下内容:

  • Spring Cloud 采用 Consul 作为注册中心该如何实现
  • Spring Cloud 采用 Consul 作为配置中心该如何实现
2. 整体架构

Consul 作为服务注册中心的思路是各个服务将自身注册到 Consul,调用方从 Consul 获取特定服务的提供方列表,再访问服务提供方进行服务的调用。当 Consul 中某个服务的提供方进行增减时,调用方会通过 Consul 感知到这一变化并进行负载轮询列表更新,实现服务的在线扩容。

Consul 作为配置中心的思路是各个服务启动后先连接 Consul 服务,并从其 KV 存储中按优先级获取相应的配置项,并将配置加载到程序中,可以形象地比喻为将 application.yml 配置服务化。当 Consul 中配置更新时,依赖的服务可以定期检测到这个变化并应用到程序中,实现在线配置更新。

3. Consul 搭建 3.1 dev 模式运行

Consul 官网:https://www.consul.io/

官方文档:https://www.consul.io/docs/index.html

在 Consul 官网上 https://www.consul.io/downloads.html 下载相对应的系统版本,本文以 CentOS7 为例,将下载下来的包解压后,运行 consul 文件即可启动 dev 模式的 Consul 服务。

 chmod 777 ./consul ./consul
3.2 正常模式单机运行

dev 模式是不进行数据存储的,线上环境需要开启可存储数据的模式,非dev模式的单节点命令示例如下:

nohup ./consul-service/consul agent -server -bootstrap-expect 1 -data-dir ./consul-service/data -config-dir=./consul-service/config -client=0.0.0.0 -ui >./consul-service/consul.out&

简单解释下主要参数:

  • server : 定义 agent 运行在 server 模式。
  • bootstrap-expect :在一个 datacenter 中期望提供的 server 节点数目,当该值提供的时候,consul 一直等到达到指定 server 数目的时候才会引导整个集群,该标记不能和 bootstrap 共用。
  • bind:该地址用来在集群内部的通讯,集群内的所有节点到地址都必须是可达的,默认是 0.0.0.0。
  • data-dir:数据存储目录。
  • config-dir:配置目录。
  • client:Consul 服务侦听地址,这个地址提供 HTTP、DNS、RPC 等服务,默认是 127.0.0.1 所以不对外提供服务,如果你要对外提供服务改成 0.0.0.0。
  • ui:启动 Web 管理页面
3.3 集群运行

第一台机器 IP 为 172.17.0.3,3 台机器分别执行,均启动 ui:

consul agent -server -bootstrap-expect 3 -ui -node=node1 -client 0.0.0.0consul agent -server -bootstrap-expect 3 -ui -node=node2 -client 0.0.0.0 -join 172.17.0.3consul agent -server -bootstrap-expect 3 -ui -node=node3 -client 0.0.0.0 -join 172.17.0.3

此时三台机器上的数据会进行同步,如果需要保障客户端访问集群的可靠性,需要在中间加一层 nginx 或其他负载,配置方式此处略。

4. Consul 作为服务注册中心

本示例以 IDEA+Maven 的方式进行开发。

4.1 服务端

首先是添加 pom.xml 的依赖。

    UTF-8    UTF-8    1.8    Finchley.SR1            org.springframework.boot        spring-boot-starter-web                org.springframework.cloud        spring-cloud-starter-consul-discovery                org.springframework.boot        spring-boot-starter-test        test                            org.springframework.cloud            spring-cloud-dependencies            ${spring-cloud.version}            pom            import            

然后是配置 application.yml。

server:  port: 9201spring:  application:    name: springtest-service  message:    encoding: UTF-8  cloud:    consul:      host: 127.0.0.3      port: 8500      discovery:        register: true        instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}        service-name: ${spring.application.name}        port: ${server.port}        healthCheckPath: /actuator/health        healthCheckInterval: 15s

警告:如果您使用Spring Cloud Consul Config,上述值将需要放置在 bootstrap.yml 而不是 application.yml 中。

consul 段说明

host:consul 服务的 IP

port:consul 服务的端口

discovery 段配置说明

register:是否注册到配置中心

instance-id:实例唯一 ID

service-name:服务名

port:端口

healthCheckPath:健康检查访问路径,consul 服务器会定时访问次服务的该 url 以检测是否健康

healthCheckInterval:健康检查时间间隔

最后上代码 application.java。

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@EnableDiscoveryClient@RestController@SpringBootApplicationpublic class SpringtestServerApplication {    @Autowired    private DiscoveryClient discoveryClient;    public static void main(String[] args) {        SpringApplication.run(SpringtestServerApplication.class, args);    }    /**     * 获取所有服务     */    @RequestMapping("/services")    public Object services() {        return discoveryClient.getServices();    }    @RequestMapping("/home")    public String home() {        return "Hello World";    }}

启动后,Consul 的 Service 列表中就会出现这个服务。

此时访问 http://localhost:9201/home 会输出 Hello World。

4.2 客户端

先是配置依赖 pom.xml。

            org.springframework.boot        spring-boot-starter-web                org.springframework.cloud        spring-cloud-starter-consul-discovery                org.springframework.boot        spring-boot-starter-test        test    

接下来是配置文件 application.yml。

server:  port: 9202spring:  application:    name: springtest-client  cloud:    consul:      host: 192.168.140.128      port: 8500      discovery:        register: false

最后上代码 application.java。

@EnableDiscoveryClient@RestController@SpringBootApplicationpublic class SpringtestClientApplication {    public static void main(String[] args) {        SpringApplication.run(SpringtestClientApplication.class, args);    }    @Autowired    private LoadBalancerClient loadBalancer;    @Autowired    private DiscoveryClient discoveryClient;    @Autowired    RestTemplate restTemplate;    @Bean    @LoadBalanced    public RestTemplate restTemplate(){        return new RestTemplate();    }    /**     * 从所有服务中选择一个服务(轮询)     */    @RequestMapping("/discover")    public Object discover() {        return loadBalancer.choose("springtest-service").getUri().toString();    }    /**     * 获取所有服务     */    @RequestMapping("/services")    public Object services() {        return discoveryClient.getInstances("springtest-service");    }    @RequestMapping("test")    public String test(){        String result= restTemplate.getForEntity("http://springtest-service/home",String.class).getBody();        return result;    }}

一般常用 restTemplate.getForEntity("http://springtest-service/home",String.class) 这种方式调用,方便快捷。

此时访问 http://localhost:9202/test 会输出 Hello World。

5. Consul 作为配置中心 5.1 配置

Consul 添加 kv 的方式:http://ip:8500/ 进入 Web 管理页面,点击 key/value 进入 kv 管理页面,点击右上角 create 创建 kv。

consul 页面上添加 key 为:

config/springtest-service/data

value 为:

test:  testValue:  consul--asdf34testConfig:  test-value: consul123--asdf34

生产环境中访问 Web 管理页面比较困难,此时需要通过命令去维护,一种方式是直接用 Consul 的命令去操作,但是需要运行在有 Consul 程序的机器上,还有另外一种通用的方式就是通过 webapi 访问:

获取

curl http://ip:8500/v1/kv/config/application/data

key 为 config/application/data

返回值:

[    {        "LockIndex": 0,        "Key": "config/application/data",        "Flags": 0,        "Value": "dGVzdDoKICB0ZXN0VmFsdWU6ICBhcHBiYXNlLS1hc2RmMzQKdGVzdENvbmZpZzoKICB0ZXN0LXZhbHVlOiBhcHBiYXNlLS1hc2RmMzQ=",        "CreateIndex": 1983705,        "ModifyIndex": 1983711    }]

其中 value 是 base64 加密的,需要进行解密。

echo "dGVzdDoKICB0ZXN0VmFsdWU6ICBhcHBiYXNlLS1hc2RmMzQKdGVzdENvbmZpZzoKICB0ZXN0LXZhbHVlOiBhcHBiYXNlLS1hc2RmMzQ=" | base64 -d

得到如下明文结果:

test:  testValue:  appbase--asdf34testConfig:  test-value: appbase--asdf34

完整的一次性获取命令:

 curl  http://ip:8500/v1/kv/config/application/data |grep "Value" | sed 's/        "Value": "//' | sed 's/",//' |base64 -d 

赋值

​    curl \​        -X PUT \​        -d "aaa1231​    1234324qasd" \​        http://ip:8500/v1/kv/my-key

删除

​    curl -X DELETE   http://ip:8500/v1/kv/my-key
5.2 开发实现

本示例以 IDEA+Maven 的方式进行开发。

首先是添加 pom.xml 的依赖。

    org.springframework.boot    spring-boot-starter-web    org.springframework.boot    spring-boot-starter-actuator    org.springframework.boot    spring-boot-actuator    org.springframework.boot    spring-boot-configuration-processor    org.springframework.cloud    spring-cloud-starter-consul-discovery    org.springframework.cloud    spring-cloud-starter-consul-config    org.springframework.boot    spring-boot-starter-test    test    org.projectlombok    lombok    1.18.6

然后是配置文件 bootstrap.yml。

server:  port: 9201spring:  application:    name: springtest-service  profiles:    active: dev  cloud:    consul:      host: 127.0.0.1      port: 8500      discovery:        register: true        instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}        service-name: ${spring.application.name}        port: 9201        healthCheckPath: /actuator/health        healthCheckInterval: 15s      config:        enabled: true        format: YAML        prefix: config        defaultContext: application        profileSeparator: ','        data-key: data

注:discovery 段是添加到 consul 注册中心的。

config 段说明:enabled:true 允许配置中心

format:YAML 表示 consul 中的 key-value 中的 value 内容,采用 YAML 格式,据说有四种 YAML PROPERTIES KEY-VALUE FILES

prefix: config 表示 consul 用于存储配置的文件夹根目录名为 config

defaultContext: application 表示配置文件对应的默认应用名称(优先获取当前服务名称配置,没有的到 application 里找)

profileSeparator: ',' 表示如果有多个 profile(eg:开发环境 dev,测试环境 test……),则 key 名中的 profile 与 defaultContext 之间,用什么分隔符来表示(例如 config/springtest-service,dev/data)

data-key: data 表示最后一层节点的 key 值名称,一般默认为 data

接下来是一个配置读取类 TestConfig.java。

import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.context.annotation.Configuration;@ConfigurationProperties(prefix = "test-config")@Configuration@Datapublic class TestConfig {    private String testValue;}

最后是一个测试程序 App.java。

App.java

@EnableDiscoveryClient@RestController@SpringBootApplicationpublic class SpringtestServerApplication {    @Autowired    private DiscoveryClient discoveryClient;    @Value("${test.testValue}")    private String testValue;    @Autowired    private TestConfig  testConfig;    public static void main(String[] args) {        SpringApplication.run(SpringtestServerApplication.class, args);    }    @RequestMapping("/test")    public String test(String id) {        return "test"+id+"/"+testValue+"/"+testConfig.getTestValue();    }}

这里面采用了两种获取配置的方式:@Value 和 @ConfigurationProperties,都能进行配置获取,但是后者可以实现配置更新后动态更新。

5.3 配置优先级

优先级上面的最高。

config/testApp,dev/config/testApp/config/application,dev/config/application/
6. 总结

综上,讲述了 Consul 如何部署, Spring Cloud 采用 Consul 作为注册中心和配置中心该如何实现,希望能够给大家带来帮助。

本文首发于 GitChat,未经授权不得转载,转载需与 GitChat 联系。

阅读全文: http://gitbook.cn/gitchat/activity/5c9db44771bc5c38e5b1ba31

您还可以下载 CSDN 旗下精品原创内容社区 GitChat App ,阅读更多 GitChat 专享技术内容哦。

FtooAtPSkEJwnW-9xkCLqSTRpBKX

关注
打赏
1688896170
查看更多评论

蔚1

暂无认证

  • 2浏览

    0关注

    4645博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文
立即登录/注册

微信扫码登录

0.0836s