所需工具:
工具 下载地址 本文使用版本
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刷新页面。

完毕!

nginx+consul-template+consul实现自动负载均衡的更多相关文章

  1. 通过Nginx、Consul、Upsync实现动态负载均衡和服务平滑发布

    前提 前段时间顺利地把整个服务集群和中间件全部从UCloud迁移到阿里云,笔者担任了架构和半个运维的角色.这里详细记录一下通过Nginx.Consul.Upsync实现动态负载均衡和服务平滑发布的核心 ...

  2. Consul-template+nginx实现自动负载均衡

    前言 consul-template 是 Consul 的一个守护程序,使用 consul-template 可以方便快速的实现对 Consul Key/Value 存储系统的访问,可以从 KV 系统 ...

  3. nginx作反向代理,实现负载均衡

    nginx作反向代理,实现负载均衡按正常的方法安装好 ngixn,方法可参考http://www.cnblogs.com/lin3615/p/4376224.html其中作了反向代理的服务器的配置如下 ...

  4. nginx的概念与几种负载均衡算法

    Nginx的背景 Nginx和Apache一样都是一种WEB服务器.基于REST架构风格,以URI(Uniform Resources Identifier,统一资源描述符)或URL(Uniform ...

  5. nginx之rewrite重写,反向代理,负载均衡

    rewrite重写(伪静态): 在地址栏输入xx.com/user-xxx.html, 实际上访问的就是xxx.com/user.php?id=xxx rewrite就这么简单 附上ecshop re ...

  6. nginx Win下实现简单的负载均衡(2)站点共享Session

    快速目录: 一.nginx Win下实现简单的负载均衡(1)nginx搭建部署 二.nginx Win下实现简单的负载均衡(2)站点共享Session 三.nginx Win下实现简单的负载均衡(3) ...

  7. Nginx代理与反向代理、负载均衡实

    通过 Nginx 提供的反向代理和负载均衡功能,可以合理的完成业务的分配,提高网站的处理能力:同时利用缓存功能,还可以将不需要实时更新的动态页面输出结果,转化为静态网页形成缓存,从而提高网站的响应速度 ...

  8. 001/Nginx高可用模式下的负载均衡与动静分离(笔记)

    Nginx高可用模式下的负载均衡与动静分离 Nginx(engine x)是一个高性能的HTTP和反向代理服务器,具有内存少,并发能力强特点. 1.处理静态文件.索引文件以及自动索引:打开文件描述符缓 ...

  9. 在Linux上使用Nginx为Solr集群做负载均衡

    在Linux上使用Nginx为Solr集群做负载均衡 在Linux上搭建solr集群时需要用到负载均衡,但测试环境下没有F5 Big-IP负载均衡交换机可以用,于是先后试了weblogic的proxy ...

  10. LVS + keepalived + nginx + tomcat 实现主从热备 + 负载均衡

    前言 首先声明下,由于这两天找资料,看了不少博客 ,但是出于不细心,参考者的博客地址没有记录下来,所有文中要是出现了与大家博客相同的地方,那么请大家在评论区说明并附上博客地址,我好引用进来:这里表示抱 ...

随机推荐

  1. CSS——设置边框渐变色

    前言 最近在写一个typecho的主题,刚好遇到这样一个问题就记录下吧 步骤 这是一个CSS的过度效果,效果如下. 代码 .object{ width: 50px; height: 50px; bac ...

  2. linux中添加自定义命令

    centos下设置alias别名,比较简单,例如: vim /root/.bashrc addalias rm='rm -i' Linux alias设置指令的别名命令详解 功能说明:设置指令的别名. ...

  3. django-购物车添加

    商品详情页detail.html添加加入购物车按钮 <a href="javascript:;" sku_id="{{ sku.id }}" class= ...

  4. SIGAI机器学习第二十四集 聚类算法1

    讲授聚类算法的基本概念,算法的分类,层次聚类,K均值算法,EM算法,DBSCAN算法,OPTICS算法,mean shift算法,谱聚类算法,实际应用. 大纲: 聚类问题简介聚类算法的分类层次聚类算法 ...

  5. Python爬虫进阶 | 多线程

    一.简介 为了提高爬虫程序效率,由于python解释器GIL,导致同一进程中即使有多个线程,实际上也只会有一个线程在运行,但通过request.get发送请求获取响应时有阻塞,所以采用了多线程依然可以 ...

  6. System.getProperty、PropConfig.loadConfig应用

    1.获取项目下制定位置(System.getProperty("admin.root")): 在web.xml中配置webAppRootKey <context-param& ...

  7. 计蒜客 39268.Tasks-签到 (The 2019 ACM-ICPC China Shannxi Provincial Programming Contest A.) 2019ICPC西安邀请赛现场赛重现赛

    Tasks It's too late now, but you still have too much work to do. There are nn tasks on your list. Th ...

  8. 66、Spark Streaming:数据处理原理剖析与源码分析(block与batch关系透彻解析)

    一.数据处理原理剖析 每隔我们设置的batch interval 的time,就去找ReceiverTracker,将其中的,从上次划分batch的时间,到目前为止的这个batch interval ...

  9. 最新版-Python和Java实现Aes相互加解密

    前情 需要使用Python和Java实现同一个AES加解密算法,使Python版本加密的密文能够由Java代码解密,反之亦然. Python实现 Python为3.6版本 # -*- coding: ...

  10. SQL Server 变量定义

    declare @id intdeclare @name char(10) --注意:char(10)为10位,要是位数小了会让数据出错set @id=1 set @name='sssss'selec ...