一、理论概述

服务发现的概念简述

在以前使用的是,N台机器运行了N个服务,客户端必须要知道这N个服务各自的网络位置,以前的做法是配置在配置文件中,或者有些配置在数据库中。

问题:

  1. 需要配置N个服务的网络位置,加大配置的复杂性
  2. 每个服务如果改变网络位置,那么都需要改变每个调用者的配置,以便调用到该服务
  3. 集群的情况下,难以做负载(反向代理的方式除外)

服务发现就是解决这些问题的

服务发现明显的改变就是多了一个服务发现模块

服务A-N把当前自己的网络位置注册到服务发现模块(这里注册的意思就是告诉),服务发现就以K-V的方式记录下,K一般是服务名,V就是IP:PORT。服务发现模块定时的轮询查看这些服务能不能访问的了(这就是健康检查)。客户端在调用服务A-N的时候,就跑去服务发现模块问下它们的网络位置,然后再调用它们的服务。这样的方式是不是就可以解决上面的问题了呢?客户端完全不需要记录这些服务网络位置,客户端和服务端完全解耦!

consul简述

consul是个什么,我认为准确的来讲它是个服务发现框架,并且它就是提供服务发现的工具。另外常用的还有zookeeper、eureka、etcd,现在一般大多数应用于微服务场景

详细参考这篇文档

  • consul特性

service discovery:consul通过DNS或者HTTP接口使服务注册和服务发现变的很容易,一些外部服务,例如saas提供的也可以一样注册。

health checking:健康检测使consul可以快速的告警在集群中的操作。和服务发现的集成,可以防止服务转发到故障的服务上面。

key/value storage:存储动态配置的系统。提供简单的HTTP接口,比如:存储各个服务的网络位置

multi-datacenter:无需复杂的配置,即可支持任意数量的区域。

  • 一般我们为了减少不必要的部署和维护代价,减少容错率。面对这些要求,可以有两种架构方案。
  1. docker+etcd+confd+Nginx
  2. docker+consul+Nginx

二、部署docker+consul+Nginx案例

部署此案例目的,在于对consul有个入门的了解

本案例中,使用Nginx做的web服务器,用到了处理动态页面的Tomcat,而Tomcat每次增加一个,减少一个,都要手动修改Nginx配置文件,并且发送信号给Nginx进行重载配置。本案例所有Tomcat都是运行在容器之内的,使用consul实现服务发现

环境

主机名 ip 角色信息
Nginx 192.168.111.3 consul server
docker1 192.168.111.4 consul client
docker2 192.168.111.5 consul client

自己组织语言简述下集群运行流程:首先,本案例Tomcat实在容器里头跑的,Tomcat连接到本机的registrator,该组件是向consul集群中在本机上的consul agent client注册并且存储自身服务的相关数据,agent client 会将服务注册的数据信息,发送给server,如果是有多台server的话,那么就会产生leader来负责同步各个server之间的信息,本案例由于环境限制只有一个server,而我们部署在server上的consul template软件监听相应的数据变化,然后加载到Nginx的主配置文件,Nginx主进程加载配置文件,省去了人工的很多精力,自动的添加/移除Tomcat的增减。

  • 安装

Consul 下载地址:https://www.consul.io/downloads.html ,下载后解压就是一个可执行的二进制文件consul,配置好环境变量,检查 consul 是否可用:



#unzip consul_1.5.1_linux_amd64.zip
#mv consul /usr/local/bin/consul
#consul --version
  • Consul agent
  1. 安装成功后,consul agent必须在每个consul节点上运行,所有运行consulagent节点构成consul集群。
  2. consul默认是client模式运行,提供服务注册、健康检查、转发查询给server leader。

    consul client 模式就是客户端模式,所有注册到这台client节点的服务会把相关数据转发到server,其本身并不支持持久化这些信息。

那么所谓的server模式,就是表明这个consul是个server,它的功能和client都一样,唯一不同的是,它会把所有的信息持久化到本地,这样即使故障发生,信息也是会被保留。

server-leader,意思是它是所有server的领导,和server所不一样的是,他需要负责互相给各个server同步各个server的注册信息;也负责各个节点的健康监测

  • Consul Template

Consul Template是Consul官方提供的一个工具,严格的来说不是标准的服务发现方式。这个工具会通过Consul监听数据变化然后替换模板中使用的标签,并发布替换后的文件到指定的目录。在nginx等web服务器做反向代理和负载均衡时特别有用。

  • registrator

程序会检查容器运行状态自动注册和注销docker容器的服务到服务配置中心,支持consul、etcd和skyDNS2.

部署

  • 启动consul
[root@nginx ~]# nohup consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.111.3 -client=0.0.0.0 -node=consul-server01 &>/var/log/consul.log &[1] 101674
[root@nginx ~]# ps aux | grep consul
root 101674 2.5 2.6 180012 26736 pts/1 Sl 19:45 0:00 consul agent -server -bootstrap -ui -data-dir=/var/lib/consul-data -bind=192.168.111.3 -client=0.0.0.0 -node=consul-server01 #nohup:后台运行
#-server:agent 以 server 模式启动的节点。一个数据中心中至少包含 1 个 server 节点。
#-bootstrap:用来控制一个server是否在bootstrap模式,在一个datacenter中只能有一个server处于bootstrap模式,当一个server处于bootstrap模式时,可以自己选举为raft leader
#-bind:该地址用来在集群内部的通讯,集群内的所有节点到地址都必须是可达的,默认是0.0.0.0
#-client:consul绑定在哪个client地址上,这个地址提供HTTP、DNS、RPC等服务,默认是127.0.0.1
#-node:节点在集群中的名称,在一个集群中必须是唯一的,默认是该节点的主机名
#-ui:使用自带的web UI 页面。

参数参考

[root@nginx ~]# consul members
Node Address Status Type Build Protocol DC Segment
consul-server01 192.168.111.3:8301 alive server 1.5.1 2 dc1 <all>
#consul 集群信息
[root@nginx ~]# netstat -lnpt | grep consul
tcp 0 0 192.168.111.3:8300 0.0.0.0:* LISTEN 101674/consul
tcp 0 0 192.168.111.3:8301 0.0.0.0:* LISTEN 101674/consul
tcp 0 0 192.168.111.3:8302 0.0.0.0:* LISTEN 101674/consul
tcp6 0 0 :::8500 :::* LISTEN 101674/consul
tcp6 0 0 :::8600 :::* LISTEN 101674/consul

端口解释

端口号 协议 功能
8300 TCP agent server使用的,用于处理其他agent发来的请求
8301 TCP 、UDP agent使用此端口处理LAN中的gossip
8302 TCP 、UDP agent server使用此端口处理WAN中的与其他server的gossip
8400 TCP agent用于处理从CLI来的RPC请求
8500 TCP agent用于处理HTTP API
8600 TCP 、UDP agent用于处理 DNS 查询
  • 部署registrator

  • 两个client部署社区版docker

[root@localhost ~]# yum -y install yum-utils device-mapper-persistent-data lvm2
#安装依赖 [root@localhost ~]# wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/centos/docker-ce.repo
#下载docker的repo [root@localhost ~]# yum -y install docker-ce [root@localhost ~]# mkdir /etc/docker
[root@localhost ~]# vim /etc/docker/daemon.json {
"registry-mirrors":["https://*******.mirror.aliyuncs.com"]
}
#阿里云镜像加速 #systemctl start docker

地址需要个人前往阿里云获得,参考这篇文档

  • 以下两个client同样操作
[root@docker2 ~]# docker run -d --name=registrator --net=host -v /var/run/docker.sock:/tmp/docker.sock --restart=always gliderlabs/registrator:latest -ip=192.168.111.4 consul://192.168.111.3:8500

#下载一个registrator镜像运行一个容器,指定consulserver地址111.3,本机consul地址111.4

[root@docker1 ~]# docker run -itd -p 8081:8080 --name tomcat-01 -h tom01 tomcat
#--name 是容器名称,-h是该容器的主机名称,然后会从镜像仓库下载Tomcat镜像
[root@docker1 ~]# docker run -itd -p 8082:8080 --name tomcat-02 -h tom02 tomcat
61e165ac125b394d61e8e356a4f172a1533c1bc552edbf4cace7e6e5de3b43d3
[root@docker1 ~]# docker run -itd -p 8083:8080 --name tomcat-03 -h tom03 tomcat
fd7f9246b2d6e754b011dda136d74b9f61f10a7d401165e1ee1cb36d0f2383f8
[root@docker1 ~]# docker run -itd -p 8084:8080 --name tomcat-04 -h tom04 tomcat
0e6d3dc673a61c63729f3715179efd26b481bdc94edd56ea46ed2e3aa1af8a91
#两个容器主机相同操作
  • consul-template安装:

只需要下载可执行文件:https://releases.hashicorp.com/consul-template/

将执行文件解压放到/usr/local/bin/下即可

consul-template是基于consul自动替换配置文件的应用。作为守护进程运行,实时查询consul集群信息,更新文件系统上的任意数量的指定模板,生成配置文件,更新完成以后可以选择运行shell命令执行更新操作重加载服务。

该程序可以查询consul的服务目录、key、key-values等,特别适合动态的创安金配置文件,例如Nginx,Apache,haproxy等。

[root@nginx ~]# mkdir consul
[root@nginx ~]# cd consul/
[root@nginx consul]# ls
[root@nginx consul]#
[root@nginx consul]# vim nginx.ctmpl
#配置一个模板 upstream tomcatback {
{{range service "tomcat"}}
server {{.Address}}:{{.Port}};
{{end}}
}
server {
listen 80;
server_name localhost 192.168.111.3;
access_log /usr/local/nginx/logs/joinbest-access.log;
index index.html index.jsp;
location / {
root /usr/share/nginx/html/;
index index.html;
} location /stub_status {
stub_status;
}
location ~ \.jsp$ {
proxy_pass http://tomcatback;
}
}

随后安装Nginx


[root@nginx consul]# vim /usr/local/nginx/conf/nginx.conf
http{
...
include vhost/*.conf;
}
#引用其他的文件 [root@nginx consul]# mkdir /usr/local/nginx/conf/vhost
#nginx
#启动服务
  • 配置template并启动
[root@nginx consul]# unzip consul-template_0.20.0_linux_amd64.zip
Archive: consul-template_0.20.0_linux_amd64.zip
inflating: consul-template [root@nginx consul]# mv consul-template /usr/local/bin/ [root@nginx consul]# consul-template -consul-addr 192.168.111.3:8500 -template "/root/consul/nginx.ctmpl:/usr/local/nginx/conf/vhost/nginx_tomcat.conf:/usr/local/nginx/sbin/nginx -s reload" --log-level=info #-consul-addr:指定server(leader)所在的主机和端口,程序要从这里获取服务的信息来进行下去
#-template:模板文件位置:根据模板结合服务配置生成的文件放置的位置及名称:改动之后重载文件的命令
#--log-level:表示输出信息的级别,这里为info

紧接着,因为是守护进程,会占用终端,所以平时都是用nohup命令使其后台运行

在开启一个终端,查看刚生成配置文件

[root@nginx ~]# cat /usr/local/nginx/conf/vhost/nginx_tomcat.conf
upstream tomcatback { server 192.168.111.4:8081; server 192.168.111.4:8082; server 192.168.111.4:8083; server 192.168.111.4:8084; server 192.168.111.4:8081; server 192.168.111.4:8082; server 192.168.111.4:8083; server 192.168.111.4:8084; }
server {
listen 80;
server_name localhost 192.168.111.3;
access_log /usr/local/nginx/logs/joinbest-access.log;
index index.html index.jsp;
location / {
root /usr/share/nginx/html/;
index index.html;
} location /stub_status {
stub_status;
}
location ~ \.jsp$ {
proxy_pass http://tomcatback;
}
}

虽然看起来没毛病,但是容器地址怎么能是一样的呢,应该有111.5的啊

想起来了,上面运行 registrator镜像时候,我将自身在集群中显示的ip还是111.4,疏忽了

解决

[root@docker2 ~]# docker stop `docker ps | awk 'NR!=1 {print $1}'`
[root@docker2 ~]# docker rm `docker ps -a | awk 'NR!=1 {print $1}'`
#之前容器都删除掉 [root@docker2 ~]# docker run -d --name=registrator --net=host -v /var/run/docker.sock:/tmp/docker.sock --restart=always gliderlabs/registrator:latest -ip=192.168.111.5 consul://192.168.111.3:8500
#重新运行,这下改过来ip了,注意 [root@docker2 ~]# docker run -itd -p 8081:8080 --name tomcat-01 -h tom01 tomcat
daec6a29f6399adbc167a13b383cb850f0db130097145b8479e12778834b82a3
[root@docker2 ~]# docker run -itd -p 8082:8080 --name tomcat-02 -h tom02 tomcat
83fff3139abe98522924eb5d53a1b1c3ee01fcabab593c92afb06b1b1a11a5b3
[root@docker2 ~]# docker run -itd -p 8083:8080 --name tomcat-03 -h tom03 tomcat
4d7b56307f8c5fdf9907182c7870bceaedff7686ee0fbe8c04233879009c9a6c
[root@docker2 ~]# docker run -itd -p 8084:8080 --name tomcat-04 -h tom04 tomcat
1c79ffcc488723f5f75835d19efabf79bc13bcb8bdd7ee8d52e13b58666c8623
#重新启动容器

那么,正好测试下,consul template 实用不

图2

[root@nginx ~]# cat /usr/local/nginx/conf/vhost/nginx_tomcat.conf
upstream tomcatback { server 192.168.111.4:8081; server 192.168.111.4:8082; server 192.168.111.4:8083; server 192.168.111.4:8084; server 192.168.111.5:8081; server 192.168.111.5:8082; server 192.168.111.5:8083; server 192.168.111.5:8084; }
server {
listen 80;
server_name localhost 192.168.111.3;
access_log /usr/local/nginx/logs/joinbest-access.log;
index index.html index.jsp;
location / {
root /usr/share/nginx/html/;
index index.html;
} location /stub_status {
stub_status;
}
location ~ \.jsp$ {
proxy_pass http://tomcatback;
}
}

很好

三、测试

[root@docker1 ~]# docker exec -it tomcat-01 /bin/bash -c 'echo www.tomcat1.com > /usr/local/tomcat/webapps/ROOT/index.jsp'
[root@docker1 ~]# docker exec -it tomcat-02 /bin/bash -c 'echo www.tomcat2.com > /usr/local/tomcat/webapps/ROOT/index.jsp'
[root@docker1 ~]# docker exec -it tomcat-03 /bin/bash -c 'echo www.tomcat3.com > /usr/local/tomcat/webapps/ROOT/index.jsp'
[root@docker1 ~]# docker exec -it tomcat-04 /bin/bash -c 'echo www.tomcat4.com > /usr/local/tomcat/webapps/ROOT/index.jsp' [root@docker2 ~]# docker exec -it tomcat-01 /bin/bash -c 'echo www.tomcat5.com > /usr/local/tomcat/webapps/ROOT/index.jsp'
[root@docker2 ~]# docker exec -it tomcat-02 /bin/bash -c 'echo www.tomcat6.com > /usr/local/tomcat/webapps/ROOT/index.jsp'
[root@docker2 ~]# docker exec -it tomcat-03 /bin/bash -c 'echo www.tomcat7.com > /usr/local/tomcat/webapps/ROOT/index.jsp'
[root@docker2 ~]# docker exec -it tomcat-04 /bin/bash -c 'echo www.tomcat8.com > /usr/local/tomcat/webapps/ROOT/index.jsp'

测试浏览器,访问192.168.111.3/index.jsp看到页面不断更换

四、总结

  1. 讲真,实验很简单,原理很深厚,服务发现以前没接触过,到现在也只能说能勉强理解点
  2. 这些工具适用于需要大量容器环境,并且服务性质是一样的,要不然还不如手动改改配置得了
  3. 不过挺有成就感的呢,嘻嘻

服务发现之consul理论整理_结合Docker+nginx+Tomcat简单部署案例的更多相关文章

  1. ASP.NET Core 微服务初探[1]:服务发现之Consul

    ASP.NET Core 微服务初探[1]:服务发现之Consul   在传统单体架构中,由于应用动态性不强,不会频繁的更新和发布,也不会进行自动伸缩,我们通常将所有的服务地址都直接写在项目的配置文件 ...

  2. 服务发现比较:Consul vs Zookeeper vs Etcd vs Eureka

    原文:https://blog.csdn.net/dengyisheng/article/details/71215234 服务发现比较:Consul vs Zookeeper vs Etcd vs ...

  3. 初识服务发现及Consul框架的简单使用

    初识服务发现及Consul框架的简单使用   1.什么是服务发现? 服务发现组件记录了(大规模)分布式系统中所有服务的信息,人们或者其它服务可以据此找到这些服务. DNS 就是一个简单的例子. 当然, ...

  4. 服务发现(consul)搭建

    服务发现(consul)搭建 下载最新版 consul 本人使用的版本为1.5.1,操作系统:window server 2008 consul部署的时候分为客户端和服务端,本次操作服务器2台,客户端 ...

  5. .Net微服务实践(五)[服务发现]:Consul介绍和环境搭建

    目录 介绍 服务发现 健康检查.键值存储和数据中心 架构 Consul模式 环境安装 HTTP API 和Command CLI 示例API介绍 最后 在上篇.Net微服务实践(四)[网关]:Ocel ...

  6. 服务注册发现consul之三:服务发现比较:Consul vs Zookeeper vs Etcd vs Eureka

    这里就平时经常用到的服务发现的产品进行下特性的对比,首先看下结论: Feature Consul zookeeper etcd euerka 服务健康检查 服务状态,内存,硬盘等 (弱)长连接,kee ...

  7. docker容器的服务发现:consul

    官网:https://www.consul.io 官网文档:https://www.consul.io/docs简介 consul是一个服务发现的组件,在docker世界中他比较流行,主要是consu ...

  8. 服务发现之consul的介绍、部署和使用

    什么是服务发现 微服务的框架体系中,服务发现是不能不提的一个模块.我相信了解或者熟悉微服务的童鞋应该都知道它的重要性.这里我只是简单的提一下,毕竟这不是我们的重点.我们看下面的一幅图片:     图中 ...

  9. 服务发现--初识Consul

    前言 服务注册.服务发现作为构建微服务架构得基础设施环节,重要性不言而喻.在当下,比较热门用于做服务注册和发现的开源项目包括zookeeper.etcd.euerka和consul.今天在这里对近期学 ...

随机推荐

  1. Egret中图片颜色的改变,颜色矩阵

    参考: 图片处理:颜色矩阵和坐标变换矩阵 Egret-滤镜 之前面试有问到如何改变图片的颜色.貌似之前做Flash的时候做过,做Egret后没有此类需求,所以一直没有研究过. 现在来弄一弄如何改变图片 ...

  2. 【JQuery插件】扑克正反面翻牌效果

    里面有两个demo,支持X横向和Y纵向翻转两个效果. 对元素的布局有一定的讲究,需要分析一下demo的css. 默认翻转速度为80,不要大于100ms. <!DOCTYPE> <ht ...

  3. Web书写Test Case时需要考虑的检查点

    通常书写Test Case时需要考虑的检查点: 一. 对于屏幕显示来说包括:1.检查显示的布局:2.检查域和按钮的顺序:3.检查域的尺寸:4.检查字体的大小和风格:5.检查文本的含义:6.检查拼写错误 ...

  4. 安装Vim插件——ViPlugin

    打开Eclipse,找到Help——Install New Software  Name输入 viPlugin ,Location输入 viplugin.com ,点击OK 之后同意协议,然后等待下载 ...

  5. spark kmer计算

    输入文件:fa格式的文件 输出结果:kmer的频数和对应的kmer类型和计数 1.将fq.gz的文件转换成fa文件: #!/usr/bin/python env # -*- coding:utf-8 ...

  6. GraphHopper-初识

    GraphHopper  GraphHopper is a fast and Open Source road routing engine.   Is fast and memory efficie ...

  7. Jenkins+maven+gitlab自动化部署之前端构建发布(六)

    前端项目构建,需要在jenkins主机部署node服务,网上有说介绍说安装对应的nodejs插件进行前端项目构建,我这里是直接调用系统npm命令,进行前端打包.具体node部署参考:Centos7部署 ...

  8. struts下载文件错误,想不明白为什么更改变量名就不报错了

    java.lang.IllegalArgumentException: Can not find a java.io.InputStream with the name [is] in the inv ...

  9. Struts笔记3

    struts标签 form表单标签 Action:请求地址.直接写动作名称,不用写contextPath <s:form action="/user/register.action&q ...

  10. [C++] 习题 2.14 用队列实现桶排序

    目录 前置技能 队列(已在上篇提到栈的时候顺便提到了,不再赘述) 桶排序 具体实现 由用户输入n个10以内的数,每输入i(0≤i≤9),就把它插入第i号队列中,最后把10个队列中的非空队列,按队列号从 ...