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

    完毕!

  • 相关阅读:
    atitit 提升数据库死锁处理总结
    CoreJava_线程并发(堵塞队列):在某个目录下搜索含有某keyword的文件
    HDU 4389——X mod f(x)(数位DP)
    POJ 1182 (经典食物链 /并查集扩展)
    【iOS-Android开发对照】 之 APP入口
    《Pro Android Graphics》读书笔记之第四节
    Android多个Module统一配置相同jar或库的版本号
    教你上传代码到码云(与github一样)
    解决本地项目推送到码云(github),上提示:failed to push some refs to ...
    android adb常用指令
  • 原文地址:https://www.cnblogs.com/ExMan/p/11944904.html
Copyright © 2020-2023  润新知