nginx+consul-template+consul实现自动负载均衡

所需工具:
工具 下载地址 本文使用版本
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 执行,或者参见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刷新页面。

完毕!

猜你喜欢

转载自www.cnblogs.com/ExMan/p/11944904.html