使用consul实现服务的注册和发现

来源:互联网 发布:java的clone方法 编辑:程序博客网 时间:2024/05/21 15:06

转载地址:http://blog.csdn.net/mn960mn/article/details/51768678


服务注册 - 服务进程在注册中心注册自己的位置。它通常注册自己的主机和端口号,有时还有身份验证信息,协议,版本号,以及运行环境的详细资料。

服务发现 - 客户端应用进程向注册中心发起查询,来获取服务的位置。服务发现的一个重要作用就是提供一个可用的服务列表

服务定义的格式类似如下:

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. {  
  2.   "service":{  
  3.     "id": "jetty",  
  4.     "name": "jetty",  
  5.     "address": "192.168.1.200",  
  6.     "port": 8080,  
  7.     "tags": ["dev"],  
  8.     "checks": [  
  9.         {  
  10.             "http": "http://192.168.1.200:8080/health",  
  11.             "interval": "5s"  
  12.         }  
  13.     ]  
  14.   }  
  15. }  

其中,check是用来做服务的健康检查的,可以有多个,也可以没有,支持多种方式的检查

check必须是script或者TTL类型的,如果是script类型,则script和interval变量必须被提供,如果是TTL类型,则ttl变量必须被提供

script是consul主动去检查服务的健康状况,ttl是服务主动向consul报告自己的健康状况

以下是几种配置方式

script check

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. {  
  2.   "check": {  
  3.     "id": "mem-util",  
  4.     "name": "Memory utilization",  
  5.     "script": "/usr/local/bin/check_mem.py",  
  6.     "interval": "10s",  
  7.     "timeout": "1s"  
  8.   }  
  9. }  

HTTP check:

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. {  
  2.   "check": {  
  3.     "id": "api",  
  4.     "name": "HTTP API on port 5000",  
  5.     "http": "http://localhost:5000/health",  
  6.     "interval": "10s",  
  7.     "timeout": "1s"  
  8.   }  
  9. }  

TCP check:

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. {  
  2.   "check": {  
  3.     "id": "ssh",  
  4.     "name": "SSH TCP on port 22",  
  5.     "tcp": "localhost:22",  
  6.     "interval": "10s",  
  7.     "timeout": "1s"  
  8.   }  
  9. }  

TTL check:

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. {  
  2.   "check": {  
  3.     "id": "web-app",  
  4.     "name": "Web App Status",  
  5.     "notes": "Web app does a curl internally every 10 seconds",  
  6.     "ttl": "30s"  
  7.   }  
  8. }  

注册服务,有三种方式,
1:通过配置文件的方式静态注册
创建文件夹/etc/consul.d 
.d代表有许多配置文件在里面
vim /etc/consul.d/jetty.json  内容如下:

[plain] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. {  
  2.   "service":{  
  3.     "id": "jetty",  
  4.     "name": "jetty",  
  5.     "address": "192.168.1.200",  
  6.     "port": 8080,  
  7.     "tags": ["dev"],  
  8.     "checks": [  
  9.         {  
  10.             "http": "http://192.168.1.200:8080/health",  
  11.             "interval": "5s"  
  12.         }  
  13.     ]  
  14.   }  
  15. }  

重启consul,并将配置文件的路径给consul(指定参数:-config-dir /etc/consul.d)

2:通过HTTP API接口来动态注册
直接调用/v1/agent/service/register接口注册即可,需要注意的是:http method为PUT提交方式

如:

curl -X PUT -d '{"id": "jetty","name": "jetty","address": "192.168.1.200","port": 8080,"tags": ["dev"],"checks": [{"http": "http://192.168.1.104:9020/health","interval": "5s"}]}' http://192.168.1.100:8500/v1/agent/service/register


注意,这种方式,和上面的注册方式有一点不一样,body的参数,是上面service的值,这点需要注意


3:使用程序实现服务的注册和发现(Java)

首先加入consul client的依赖

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <dependency>  
  2.     <groupId>com.orbitz.consul</groupId>  
  3.     <artifactId>consul-client</artifactId>  
  4.     <version>0.12.3</version>  
  5. </dependency>  

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. package com.pp.cnosul;  
  2.   
  3. import com.google.common.net.HostAndPort;  
  4. import com.orbitz.consul.AgentClient;  
  5. import com.orbitz.consul.Consul;  
  6. import com.orbitz.consul.HealthClient;  
  7. import com.orbitz.consul.model.agent.ImmutableRegCheck;  
  8. import com.orbitz.consul.model.agent.ImmutableRegistration;  
  9.   
  10. public class ConsulDemo {  
  11.   
  12.     static Consul consul = Consul.builder().withHostAndPort(HostAndPort.fromString("192.168.1.246:8500")).build();  
  13.   
  14.     /** 
  15.      * 服务注册 
  16.      */  
  17.     public static void serviceRegister() {  
  18.         AgentClient agent = consul.agentClient();  
  19.           
  20.         //健康检测  
  21.         ImmutableRegCheck check = ImmutableRegCheck.builder().http("http://192.168.1.104:9020/health").interval("5s").build();  
  22.           
  23.         ImmutableRegistration.Builder builder = ImmutableRegistration.builder();  
  24.         builder.id("tomcat1").name("tomcat").addTags("v1").address("192.168.1.104").port(8080).addChecks(check);  
  25.           
  26.         agent.register(builder.build());  
  27.     }  
  28.       
  29.     /** 
  30.      * 服务获取 
  31.      */  
  32.     public static void serviceGet() {  
  33.         HealthClient client = consul.healthClient();  
  34.         String name = "tomcat";  
  35.         //获取所有服务  
  36.         System.out.println(client.getAllServiceInstances(name).getResponse().size());  
  37.           
  38.         //获取所有正常的服务(健康检测通过的)  
  39.         client.getHealthyServiceInstances(name).getResponse().forEach((resp) -> {  
  40.             System.out.println(resp);  
  41.         });  
  42.     }  
  43.       
  44.     public static void main(String[] args) {  
  45.         serviceRegister();  
  46.         serviceGet();  
  47.     }  
  48. }  

当然了,还可以使用如下consul api

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <dependency>  
  2.     <groupId>com.ecwid.consul</groupId>  
  3.     <artifactId>consul-api</artifactId>  
  4.     <version>1.1.10</version>  
  5. </dependency>  

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. import com.ecwid.consul.v1.ConsulClient;  
  2. import com.ecwid.consul.v1.ConsulRawClient;  
  3. import com.ecwid.consul.v1.agent.model.Service;  
  4.   
  5. public class App {  
  6.       
  7.     public static void main(String[] args) {  
  8.         ConsulRawClient client = new ConsulRawClient("192.168.1.100"8500);  
  9.         ConsulClient consul = new ConsulClient(client);  
  10.         //获取所有服务  
  11.         Map<String, Service> map = consul.getAgentServices().getValue();  
  12.     }  
  13. }  

其中,spring cloud 使用的就是第二种consul api
0 0