当我们新添加一个微服务实例的时候,微服务就会将自己的 ip与port 发送到注册中心,在注册中心里面记录起来。当APl gateway需要访问某些微服务的时候,就会去注册中心取到相应的ip与port。从而实现自动化操作。
Consul 简化了分布式环境中的服务的注册和发现流程,通过 HTTP 或者 DNS 接口发现。支持外部 SaaS 提供者等。
grpc健康检查重要点:
1.check = {
“GRPC": rtipH:{port}","GRPCUseTLS": False,"Timeout": "5s"","Interval": "5s",
"DeregisterCriticalServiceAfter": "5s",
}
2.一定要确保网络是通的
3.一定要确保srv服务监听端口是对外可访问的
4.GRPC一定要自己填写
代码如下(示例):
docker run -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600/udp consul consul agent -dev -client=0.0.0.0
docker container update --restart=always 容器名字
代码如下(示例):
浏览器访问:地址:8500
该处使用的url网络请求的数据。
consul提供dns功能,可以让我们通过,可以通过dig命令行来测试,consul默认的dns端口是8600,命令行:
dig @地址 -p 8600 consul.service.onsul SRV
liunx安装dig命令:yum insatll bind-utils
官网详细使用:https://developer.hashicorp.com/consul/api-docs/agent/service
import requests
headers = {
# "contentType": "application/json"
"Content-Type": "application/json"
}
def register(name, id, address, port):
url = "http://192.168.10.130:8500/v1/agent/service/register"
rsp = requests.put(url, headers=headers, json={
"Name": name,
"ID": id,
"Tags": ["mxshop", "bobby", "imooc", "grpc"],
"Address": address,
"Port": port,
"Check": {
# "HTTP": f"http://{address}:{port}/health",
"GRPC": f"{address}:{port}",
"GRPCUseTLS": False,
"Timeout": "5s", # 超时时间
"Interval": "5s", # 五秒检测一次
"DeregisterCriticalServiceAfter": "15s", # 五秒钟检查不到 就移除服务a
}
})
if rsp.status_code == 200:
print("注册成功")
else:
print(f"注册失败{rsp.status_code}")
if __name__ == '__main__':
register("mxshop-web", "mxshop-web", "10.231.72.37", 50051)
def deregister(id):
url = f"http://192.168.10.130:8500/v1/agent/service/deregister/{id}"
rsp = requests.put(url, headers=headers)
if rsp.status_code == 200:
print("注销成功")
else:
print(f"注销失败{rsp.status_code}")
def del_all():
rsp = c.agent.services()
for key, value in rsp.items():
# print(key)
rsp = c.agent.service.deregister(key) # 注销所有
if __name__ == '__main__':
deregister("mxshop-web")
def filter_service(name):
url = "http://192.168.10.130:8500/v1/agent/services"
params = {
"filter": f'Service == "{name}"',
}
rsp = requests.get(url, params=params).json()
for k, v in rsp.items():
print(k)
if __name__ == '__main__':
filter_service("mxshop-web")
package main
import (
"fmt"
"github.com/hashicorp/consul/api"
)
func Register(address string, port int, name string, tags []string, id string) error {
cfg := api.DefaultConfig()
cfg.Address = "192.168.10.130:8500"
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}
registration := new(api.AgentServiceRegistration)
registration.Name = name
registration.ID = id
registration.Port = port
registration.Tags = tags
registration.Address = address
//生成对应的检查对象
check := &api.AgentServiceCheck{
HTTP: "http://10.231.72.37:8021/health",
Timeout: "5s",
Interval: "5s",
DeregisterCriticalServiceAfter: "10s",
}
registration.Check = check
err = client.Agent().ServiceRegister(registration)
if err != nil {
panic(err)
}
return nil
}
func main() {
_ = Register("10.231.72.37", 8021, "user-web", []string{"mxshop", "bobby"}, "user-web")
}
package main
import (
"fmt"
"github.com/hashicorp/consul/api"
)
func AllServices() {
cfg := api.DefaultConfig()
cfg.Address = "192.168.10.130:8500"
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}
data, err := client.Agent().Services()
if err != nil {
panic(err)
}
for key, _ := range data {
fmt.Println(key)
}
}
func main() {
AllServices()
}
package main
import (
"fmt"
"github.com/hashicorp/consul/api"
)
func FilterSerivice(name string) {
cfg := api.DefaultConfig()
cfg.Address = "192.168.10.130:8500"
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}
data, err := client.Agent().ServicesWithFilter(fmt.Sprintf(`Service == "%s"`,name))
if err != nil {
panic(err)
}
for key, _ := range data {
fmt.Println(key)
}
}
func main() {
FilterSerivice("user-web")
}
protobuf版本<=3.19.0
链接:https://pan.baidu.com/s/1oMPPVHLglDXafTUGP_hewg
提取码:e2if
base抽象基类
import abc
import six
@six.add_metaclass(abc.ABCMeta)
class Register():
@abc.abstractmethod
def register(self, name, id, address, port, tags, check):
pass
@abc.abstractmethod
def deregister(self, service_id):
pass
@abc.abstractmethod
def get_all_service(self):
pass
@abc.abstractmethod
def filter_service(self, filter):
pass
consul服务注册&健康检查&查找服务&删除服务
from common.register import base
import consul
import requests
class ConsulRegister(base.Register):
def __init__(self, host, port):
self.host = host
self.port = port
self.c = consul.Consul(host=host, port=port)
def register(self, name, id, address, port, tags, check) -> bool:
if check is None:
check = {
# "HTTP": f"http://{address}:{port}/health",
"GRPC": f"{address}:{port}",
"GRPCUseTLS": False,
"Timeout": "5s", # 超时时间
"Interval": "5s", # 五秒检测一次
"DeregisterCriticalServiceAfter": "15s", # 五秒钟检查不到 就移除服务a
}
else:
check = check
return self.c.agent.service.register(name=name, service_id=id,
address=address, port=port, tags=tags, check=check)
def deregister(self, service_id):
return self.c.agent.service.deregister(service_id)
def get_all_service(self):
return self.c.agent.services()
def filter_service(self, filter):
url = f"http://{self.host}:{self.port}/v1/agent/services"
params = {
"filter": filter,
}
return requests.get(url, params=params).json()
注册到grpc当中
# 注册健康检查
from common.grpc_health.v1 import health_pb2_grpc, health_pb2
from common.grpc_health.v1 import health
import grpc
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
health_servicer = health.HealthServicer()
health_pb2_grpc.add_HealthServicer_to_server(health_servicer, server)
logger.info(f"服务注册开始")
register = consul.ConsulRegister(settings.CONSUL_HOST, settings.CONSUL_PORT)
if not register.register(name=settings.SERVICE_NAME, id=settings.SERVICE_NAME,address=args.ip,port=args.port,
tags=settings.SERVICE_TAGS, check=None):
logger.info("服务注册失败")
sys.exit(0)
package initialize
import (
"fmt"
"github.com/hashicorp/consul/api"
"go.uber.org/zap"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"mxshop-api/user-web/global"
"mxshop-api/user-web/proto"
)
func InitSrvConn() {
cfg := api.DefaultConfig()
//这个是我debug.yaml映射的struct 自己需要填充即可
consulInfo := global.ServerConfig.ConsulInfo
//连接consul
cfg.Address = fmt.Sprintf("%s:%d", consulInfo.Host, consulInfo.Port)
//用来获取consul对应的host:port
userSrvHost := ""
userSrvPort := 0
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}
//查询指定的consul
data, err := client.Agent().ServicesWithFilter(fmt.Sprintf("Service == \"%s\"", global.ServerConfig.UserSrvConfig.Name))
//data, err := client.Agent().ServicesWithFilter(fmt.Sprintf(`Service == "%s"`,global.ServerConfig.UserSrvConfig.Name))
if err != nil {
panic(err)
}
//赋值 | (key,value)ID和返回的指定详细consul
for _, value := range data {
userSrvHost = value.Address
userSrvPort = value.Port
break
}
if userSrvHost == "" {
zap.S().Fatal("[InitSrvConn] 连接 【用户服务失败】")
return
}
//拨号连接用户grpc服务器
userConn, err := grpc.Dial(fmt.Sprintf("%s:%d", userSrvHost,
userSrvPort), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
zap.S().Errorw("[GetUserList] 连接 【用户服务失败】",
"msg", err.Error(),
)
}
//1.后续的用户服务下线了 2.该端口了 3.改ip了 负载均衡来做
//2.已经事先创立好了连接,这样后续就不用进行再次tcp的三次握手
//3.一个连接多个groutine共用,性能-连接池
userSrcClient := proto.NewUserClient(userConn)
global.UserSrvClient = userSrcClient
}
启动gin时初始化
package main
func main() {
//初始化srv的连接
initialize.InitSrvConn()
zap.S().Debugf("启动服务器,端口:%d", global.ServerConfig.Port)
if err := Router.Run(fmt.Sprintf(":%d", global.ServerConfig.Port)); err != nil {
zap.S().Panic("启动失败:", err.Error())
}
}
grpc健康检查重要点:
1.check = {
“GRPC": rtipH:{port}","GRPCUseTLS": False,"Timeout": "5s"","Interval": "5s",
"DeregisterCriticalServiceAfter": "5s",
}
2.一定要确保网络是通的
3.一定要确保srv服务监听端口是对外可访问的
4.GRPC一定要自己填写
python和golang的consul的服务注册、健康检查、服务发现
集成到python的srv
集成到golang的gin