Golang微服务(二)
目录注册中心
选型
注册中心要综合考虑:
- 功能是否完善
- 是否易用
- 是否可配置
- 是否支持健康检查
- 是否支持多数据中心
- 是否支持服务发现
基于上述考虑,consul是不错的选择
consul环境
文档:https://developer.hashicorp.com/consul/docs
使用docker准备上手consul的环境
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容器自启动
docker container update --restart=always
Web界面运行在8500端口
consul容器8600端口可以做DNS服务
dig @192.168.xxx.xxx -p 8600 consul.service.consul SRV
consul常用API
-
服务的增删查、健康检查
package main import ( "fmt" "github.com/hashicorp/consul/api" ) func GetClient() (*api.Client, error) { cfg := api.DefaultConfig() cfg.Address = "192.168.xxx.xxx:8500" client, err := api.NewClient(cfg) if err != nil { fmt.Println(err) return nil, err } return client, nil } // Register 注册服务 func Register(name string, address string, port int, tags []string, id string) { client, err := GetClient() if err != nil { panic(err) } registration := &api.AgentServiceRegistration{ Name: name, Address: address, Port: port, Tags: tags, ID: id, // 健康检查配置 Check: &api.AgentServiceCheck{ HTTP: "http://192.168.xxx.xxx:xxxx/h", Timeout: "5s", Interval: "10s", DeregisterCriticalServiceAfter: "20s", // 注销服务 }, } err = client.Agent().ServiceRegister(registration) if err != nil { panic(err) } } // GetAllServices 查询所有服务 func GetAllServices() { client, err := GetClient() if err != nil { panic(err) } services, err := client.Agent().Services() if err != nil { fmt.Println(err) return } for name, service := range services { fmt.Println(name, service.ID) } } // FilterServices 查询并过滤服务 func FilterServices(filter string) { client, err := GetClient() if err != nil { panic(err) } services, err := client.Agent().ServicesWithFilter(filter) // 查询语句使用services response中的字段==具体值 if err != nil { fmt.Println(err) return } for name, service := range services { fmt.Println(name, service.ID) } } // Deregister 注销服务 func Deregister(serviceID string) { client, err := GetClient() if err != nil { panic(err) } err = client.Agent().ServiceDeregister(serviceID) if err != nil { panic(err) } } func main() { Register("test", "192.168.xxx.xxx", xxx, []string{"web"}, "test") GetAllServices() FilterServices(`Service=="test"`) Deregister("test") }
-
gRPC的健康检查
import ( "google.golang.org/grpc/health" "google.golang.org/grpc/health/grpc_health_v1" ) server := grpc.NewServer() grpc_health_v1.RegisterHealthServer(server, health.NewServer()) // 注册健康检查server // 注册时的check实例也需要修改 Check: &api.AgentServiceCheck{ GRPC: "192.168.xxx.xxx:xxxx", Timeout: "5s", Interval: "10s", DeregisterCriticalServiceAfter: "20s", // 注销服务 },
-
服务的负载均衡(相同服务多实例注册)
做负载均衡的层有很多,从最初接触请求的nginx到api网关到web层都可以做负载均衡,方式也有包括集中式、进程内、独立进程等多种方式,gRPC使用的是进程内负载均衡的方式(也支持三方负载均衡),这种方式缺点是需要多语言单独实现,但是相对于集中式的超大流量和独立进程的额外维护等缺点,还是可以接受的。
负载均衡的策略也有多种。包括轮询法、随机法、源地址哈希法、加权轮询法、加权随机法、最小连接法等。
使用三方库grpc-consul-resolver完成负载均衡
import _ "github.com/mbobakov/grpc-consul-resolver" func main() { conn, err := grpc.Dial( "consul://127.0.0.1:8500/whoami?wait=14s&tag=manual", grpc.WithInsecure(), grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`), ) if err != nil { log.Fatal(err) } defer conn.Close() ... }
配置中心
常见配置中心要求:实时推送、权限、集群、配置回滚、环境隔离
选型:nacos
nacos环境
# docker搭建用于上手的nacos环境
docker run --name nacos-standalone -e MODE=standalone -e JVM_XMS=512m -e JVM_XMX=512m -e JVM_XMN=256m -p 8848:8848 -d nacos/nacos-server:latest
# 访问http://192.168.112.131:8848/nacos/index.html进入web管理界面
nacos常用功能或概念
命名空间,可以为配置集提供隔离性,一般用来区分微服务
组,一般用来区分开发、测试、生产环境
Data ID 配置集标识,一些需要聚合的配置组成的集合,可以参考一个配置文件
clientConfig := constant.ClientConfig{
NamespaceId: "e525eafa-f7d7-4029-83d9-008937f9d468", //we can create multiple clients with different namespaceId to support multiple namespace.When namespace is public, fill in the blank string here.
TimeoutMs: 5000,
NotLoadCacheAtStart: true,
LogDir: "/tmp/nacos/log",
CacheDir: "/tmp/nacos/cache",
LogLevel: "debug",
}
serverConfigs := []constant.ServerConfig{
{
IpAddr: "console1.nacos.io",
ContextPath: "/nacos",
Port: 80,
Scheme: "http",
}
}
_, _ := clients.CreateConfigClient(map[string]interface{}{
"serverConfigs": serverConfigs,
"clientConfig": clientConfig,
})
content, err := configClient.GetConfig(vo.ConfigParam{
DataId: "dataId",
Group: "group"}
标签:服务,err,nil,consul,xxx,nacos,Golang,client
From: https://www.cnblogs.com/missfxy/p/17156061.html