服務發現 - 客戶端應用進程向註冊中心發起查詢,來獲取服務的位置。服務發現的一個重要作用就是提供一個可用的服務列表
服務定義的格式類似如下:
{
"service":{
"id": "jetty",
"name": "jetty",
"address": "192.168.1.200",
"port": 8080,
"tags": ["dev"],
"checks": [
{
"http": "http://192.168.1.200:8080/health",
"interval": "5s"
}
]
}
}
其中,check是用來做服務的健康檢查的,可以有多個,也可以沒有,支持多種方式的檢查
check必須是script或者TTL類型的,如果是script類型,則script和interval變量必須被提供,如果是TTL類型,則ttl變量必須被提供
script是consul主動去檢查服務的健康狀況,ttl是服務主動向consul報告自己的健康狀況
以下是幾種配置方式
script check
{
"check": {
"id": "mem-util",
"name": "Memory utilization",
"script": "/usr/local/bin/check_mem.py",
"interval": "10s",
"timeout": "1s"
}
}
HTTP check:
{
"check": {
"id": "api",
"name": "HTTP API on port 5000",
"http": "http://localhost:5000/health",
"interval": "10s",
"timeout": "1s"
}
}
TCP check:
{
"check": {
"id": "ssh",
"name": "SSH TCP on port 22",
"tcp": "localhost:22",
"interval": "10s",
"timeout": "1s"
}
}
TTL check:
{
"check": {
"id": "web-app",
"name": "Web App Status",
"notes": "Web app does a curl internally every 10 seconds",
"ttl": "30s"
}
}
註冊服務,有三種方式,
1:通過配置文件的方式靜態註冊
創建文件夾/etc/consul.d
.d代表有許多配置文件在裏面
vim /etc/consul.d/jetty.json 內容如下:
{
"service":{
"id": "jetty",
"name": "jetty",
"address": "192.168.1.200",
"port": 8080,
"tags": ["dev"],
"checks": [
{
"http": "http://192.168.1.200:8080/health",
"interval": "5s"
}
]
}
}
重啓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的依賴
<dependency>
<groupId>com.orbitz.consul</groupId>
<artifactId>consul-client</artifactId>
<version>0.12.3</version>
</dependency>
package com.pp.cnosul;
import com.google.common.net.HostAndPort;
import com.orbitz.consul.AgentClient;
import com.orbitz.consul.Consul;
import com.orbitz.consul.HealthClient;
import com.orbitz.consul.model.agent.ImmutableRegCheck;
import com.orbitz.consul.model.agent.ImmutableRegistration;
public class ConsulDemo {
static Consul consul = Consul.builder().withHostAndPort(HostAndPort.fromString("192.168.1.246:8500")).build();
/**
* 服務註冊
*/
public static void serviceRegister() {
AgentClient agent = consul.agentClient();
//健康檢測
ImmutableRegCheck check = ImmutableRegCheck.builder().http("http://192.168.1.104:9020/health").interval("5s").build();
ImmutableRegistration.Builder builder = ImmutableRegistration.builder();
builder.id("tomcat1").name("tomcat").addTags("v1").address("192.168.1.104").port(8080).addChecks(check);
agent.register(builder.build());
}
/**
* 服務獲取
*/
public static void serviceGet() {
HealthClient client = consul.healthClient();
String name = "tomcat";
//獲取所有服務
System.out.println(client.getAllServiceInstances(name).getResponse().size());
//獲取所有正常的服務(健康檢測通過的)
client.getHealthyServiceInstances(name).getResponse().forEach((resp) -> {
System.out.println(resp);
});
}
public static void main(String[] args) {
serviceRegister();
serviceGet();
}
}
當然了,還可以使用如下consul api
<dependency>
<groupId>com.ecwid.consul</groupId>
<artifactId>consul-api</artifactId>
<version>1.1.10</version>
</dependency>
import com.ecwid.consul.v1.ConsulClient;
import com.ecwid.consul.v1.ConsulRawClient;
import com.ecwid.consul.v1.agent.model.Service;
public class App {
public static void main(String[] args) {
ConsulRawClient client = new ConsulRawClient("192.168.1.100", 8500);
ConsulClient consul = new ConsulClient(client);
//獲取所有服務
Map<String, Service> map = consul.getAgentServices().getValue();
}
}
其中,spring cloud 使用的就是第二種consul api