所需工具:

工具 下载地址 本文使用版本

consul https://www.consul.io/downloads.html consul_1.0.7_linux_amd64.zip

consul-template https://releases.hashicorp.com/consul-template/ consul-template_0.19.4_linux_amd64.zip

nginx http://nginx.org/en/download.html nginx-1.12.2.tar.g

服务器运行环境:

IP 功能 系统

192.168.188.143 consul-template, nigix CentOS-7

192.168.188.182 consul CentOS-7

192.168.188.71 consul-agent, webapp CentOS-7

192.168.188.185 consul-agent, webapp CentOS-7

1.安装consul

因为组成 consul 集群的每个成员上都要运行一个 agent,所以需要在182、71、185这三台机器上安装consul,其中182作为server,71、185作为client。

解压consul_1.0.7_linux_amd64.zip,并将其移动到/usr/bin下,这样无论在哪个目录,都可以直接使用consul命令了。

[gerrard@consul ~]#unzip consul_1.0.7_linux_amd64.zip

[gerrard@consul ~]#mv consul /usr/bin/

执行consul version查看版本,检查是否安装成功。

注意:不要忘记在182、71、185三台机器上安装。当然,如果你是虚拟机,可以安装一台,然后克隆虚拟机即可。

2.部署consul server

在182这台机器上执行:

[gerrard@consul ~]#consul agent -server -bootstrap -ui -bind 192.168.188.182 -client 192.168.188.182 -data-dir /home/gerrard/tmp/consul -node=gerrard_server01

后台运行可以用:

[gerrard@consul ~]#nohup consul agent -server -bootstrap -ui -bind 192.168.188.182 -client 192.168.188.182 -data-dir /home/gerrard/tmp/consul -node=gerrard_server01 &

agent:运行一个consul代理。

-server :切换代理到服务器模式。

-bootstrap :将服务器设置为引导模式。

-ui:启用内置的静态web UI服务器。

-data-dir:路径到数据目录存储代理状态。

-bind:设置集群通信的绑定地址。

-client:设置用于绑定客户端访问的地址。这包括RPC、DNS、HTTP和HTTPS(如果配置)。

-node:此节点的名称。 在集群中必须是唯一的,如果你运行第2台consul,可以写gerrard_server02、gerrard_server03等。

部署完,浏览器访问:http://192.168.188.182:8500/ui/#/dc1/services

 

3.部署app服务器agent

上面我们部署了consul的server,这一步,我们就来部署应用的consul代理agent服务。

在71、185机器上执行:

[gerrard@consul ~]#consul agent -data-dir /home/gerrard/tmp/consul_agent1 -node=gerrard_agent1 -bind=192.168.188.71 -join=192.168.188.182

[gerrard@consul ~]#consul agent -data-dir /home/gerrard/tmp/consul_agent2 -node=gerrard_agent2 -bind=192.168.185.185 -join=192.168.188.182

这里注意:命令中没有-server;-node不要重名;-bind地址不同,-join到第一步的consul server 的地址。

再次回到浏览器中查看:http://192.168.188.182:8500/ui/#/dc1/nodes

如下图所显示,已经多了我们刚才启动的两个agent,表示agent部署成功。

 

4.部署springboot

将springboot部署到71、185两台机器上,为agent提供具体的业务服务。

本文使用idea创建项目File ->> New ->> Project ->>Spring Initialir ->> {type:maven project ; packaging: jar} ->> {Web:Web; Cloud Discovery : Consul Discovery; Ops : Actuator} ->> Finish

spring-cloud支持consul的服务发现与注册,Actuator 支持健康检查,springboot具体配置:

pom.xml

<?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.gerrard</groupId>

<artifactId>cloud-consul</artifactId>

<version>0.0.1-SNAPSHOT</version>

<packaging>jar</packaging>


<name>cloud-consul</name>

<description>Demo project for Spring Boot</description>


<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.0.1.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.RC1</spring-cloud.version>

</properties>


<dependencies>

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


<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-actuator</artifactId>

</dependency>


<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

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


<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>


<repositories>

<repository>

<id>spring-milestones</id>

<name>Spring Milestones</name>

<url>https://repo.spring.io/milestone</url>

<snapshots>

<enabled>false</enabled>

</snapshots>

</repository>

</repositories>



</project>

application.properties

spring.cloud.consul.host=localhost

spring.cloud.consul.port=8500

spring.cloud.consul.discovery.health-check-interval=10s

spring.cloud.consul.discovery.instance-id=spring-boot-consul

spring.cloud.consul.discovery.tags=test

spring.application.name=spring-boot-consul

server.port=8080

CloudConsulApplication.class

package com.gerrard.cloudconsul;


import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;


@SpringBootApplication

@EnableDiscoveryClient

public class CloudConsulApplication {


public static void main(String[] args) {

SpringApplication.run(CloudConsulApplication.class, args);

}

}

HelloWorld.java

package com.gerrard.cloudconsul.ctrl;


import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;


@RestController

public class HelloWorld {


@RequestMapping("/")

public String index() {

return "This is index! From gerrard_agent 1!";

}


@RequestMapping("/hello")

public String hello() {

return "Hello World! From gerrard_agent 1!";

}

}

package com.gerrard.cloudconsul.ctrl;


import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;


@RestController

public class HelloWorld {


@RequestMapping("/")

public String index() {

return "This is index! From gerrard_agent 2!";

}


@RequestMapping("/hello")

public String hello() {

return "Hello World! From gerrard_agent 2!";

}

}

注意:两台服务部署的springboot所有配置应该一模一样,其中本文中两个HelloWorld controller 中返回的内容不一样,是为了后面我们测试时,区分是71、185那台服务器返回的数据,

但在实际应用中,将springboot打包后,上传到71、185的包应该是同一个包。

将jar上传至71、185服务器。用java -jar 启动springboot服务。

浏览器查看:http://192.168.188.71:8080/hello 和 http://192.168.188.185:8080/hello 查看 是否部署成功

 

回到http://192.168.188.182:8500/ui/#/dc1/services ,发现我们的应用服务 spring-boot-consul 已经出现在里边,这里的spring-boot-consul 就是在springboot的properties里配置的

至此,sprigboot部署完成。

5.安装启动nginx

在143机器上执行:

本文采用编译安装方式

[gerrard@nginx /]# cd /usr/src/

[gerrard@nginx src /]# tar -zxvf nginx-1.12.2.tar.gz

[gerrard@nginx src]# yum -y install gcc gcc-c++ make openssl-devel pcre-devel

[gerrard@nginx src]# cd nginx-1.12.2/

[gerrard@nginx nginx-1.12.2]# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_realip_module --with-pcre --with-http_ssl_module

[gerrard@nginx nginx-1.12.2]# make -j 2

[gerrard@nginx nginx-1.12.2]# make install

启动nginx

[gerrard@nginx nginx-1.12.2]# /usr/local/nginx/sbin/nginx

这里如果启动nginx报找不到什么.pid的错误,请使用sudo /sur/local/nginx/sbin/nginx 执行,

6.安装consul_template

143机器执行:

[gerrard@nginx ]# unzip consul-template_0.19.3_linux_amd64.zip[gerrard@nginx ]# mv consul-template /usr/bin/

7.配置nginx

这里先说下,nginx和consul_tempalte大概是怎么配合的,consul_tempalte启动后能够检测到consul的服务是否发生变化,比如consul_tempalte启动后就会发现目前server下有71、185两个agent代理的两个springboot服务,然后会得到这俩agent下springboot服务的ip及端口号。而nginx,反向代理,consul_tempalte就是通过模板的形式,生成一个新的nginx.conf,动态改变nginx.conf配置内代理的IP地址,从而实现添加或者减少agent而不用修改nginx配置,只需要启动或者关闭agent服务即可。比如说,忽然把185服务停掉,那么nginx代理的就只有71一台了,然后又把185启动起来,那么nginx就又代理了两台服务,或者再添加一台机器,启动agent,部署springboot,它也会自动发现。

言归正传,以下操作全在143机器上

7.1 添加模板

上面说了,consul_tempalte是通过修改模板生成一个nginx.conf,来实现动态代理,这里就要先创建模板,熟悉nginx的小伙伴肯定对下面不陌生。

在user/local/nginx/consul创建一个nginx.ctmp模板文件。

[gerrard@nginx /]#/usr/local/nginx/consul/

[gerrard@nginx /]#cd /usr/local/nginx/consul/

[gerrard@nginx consul]#vim nginx.ctmpl

粘贴下面内容到nginx.ctmpl 然后保存,这里需要注意:红色的spring-boot-consul是你springboot自己定义的名称,这里要与http://192.168.188.182:8500/ui/#/dc1/services看到的服务名一致。

upstream http_backend {

{{range service "spring-boot-consul"}}

server {{ .Address }}:{{ .Port }};

{{ end }}

}

server {

listen 8000;

server_name localhost;

location / {

proxy_pass http://http_backend;

}

}

简单描述下模板:upstream 定义一个简单的模板,server监听8000端口(你自己随便改,只要不被占用就行),反向代理到upstream。

7.2 修改nginx.conf

打开nginx.conf

[gerrard@nginx consul]# vim /usr/local/nginx/conf/nginx.conf

在server同级处,添加一句 include /usr/local/nginx/consul/*.conf; 如下图:

 

切记不要写错位置,否则你永远也访问不到你代理的地址。

配置完毕,需要重新加载nginx

[gerrard@nginx consul]# /usr/local/nginx/sbin/nginx -s reload

8.启动consul_template

至此,我们前面已经完成了,consul server、consul agent、springboot、nginx的安装、配置、部署及启动,现在还剩最后一步,启动consul_template。

143机器执行:

[gerrard@consul]# consul-template --consul-addr 192.168.188.182:8500 --template "./nginx.ctmpl:vhost.conf:/usr/local/nginx/sbin/nginx -s reload" --log-level=info

--consul-addr:consul server的地址,这里使用的是相对路径,当然你也可以使用绝对路径

--template:模板及生成的conf文件路径,后跟/usr/local/nginx/sbin/nginx -s reload是当agent发生变化时,自动重新加载nginx,如果不加,当agent发生变化时,需要你手动重新加载nginx,因为nginx配置发生了变化。

查看配置:

[gerrard@consul]# cat /usr/local/nginx/consul/vhost.conf

我们发现生成的配置文件发生了变化,多了我们的两个springboot服务。这里,如果你把71或185现在停掉其中一个,再来这里查看,就只剩一个server了。

9.验证

打开浏览器,输入http://192.168.188.143:8000/hello ,记得F5刷新页面。

 

完毕!