近来公司需要研究consul作为技术储备,本人研究了一下,所谓好记性不如烂笔头子,所以在此记录一下,也希望能帮助到需要的小伙伴,因本人技术能力有限,文章可能有不足或者错误之处,请大神指摘,好及时更改,及时刷新自己的认知。

        由于集群和负载均衡需要多台服务器测试,公司临时也没有多余服务器,所以用了虚拟机。 本文使用了两台虚拟linux作为springboot业务服务,当然你也可以使用docker。

        物理机:Mac OS X 10.13.3

        虚拟机软件:VMware-Fusion-10.1.1

        虚拟机操作系统:CentOS-7

        开发工具:IntelliJ IDEA 2017.2.7

下面我们正式开始

所需工具:
工具下载地址本文使用版本
consulhttps://www.consul.io/downloads.htmlconsul_1.0.7_linux_amd64.zip
consul-templatehttps://releases.hashicorp.com/consul-template/consul-template_0.19.4_linux_amd64.zip
nginxhttp://nginx.org/en/download.htmlnginx-1.12.2.tar.g

服务器运行环境:


IP功能系统
192.168.188.143consul-template, nigixCentOS-7
192.168.188.182consulCentOS-7
192.168.188.71consul-agent, webappCentOS-7
192.168.188.185consul-agent, webappCentOS-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/hellohttp://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 执行,或者参见 https://www.cnblogs.com/keefer/p/6188427.html

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刷新页面。


完毕!

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐