服务治理
在应用架构从单体架构向微服务架构演进的过程中,服务治理是一个重要的话题。服务治理的目标是为了解决服务的发现、注册、路由、负载均衡、熔断、限流、降级、监控、追踪等问题。 常见的治理平台如: 腾讯polarismesh,阿里nacos
woocoo可以通过配置文件方式来实现服务治 理中间件的集成.
polarismesh
腾讯开源的北极星是一个支持多语言、多框架的云原生服务发现和治理中心, 解决分布式和微服务架构中的服务可见、故障容错、流量控制和安全问题。
go get github.com/tsingsun/woocoo/polarismesh
现使用polaris默认配置的话所需的配置项很少,因此直接在woocoo配置文件中集成了.
支持能力有:
- 服务注册及发现
 - 动态路由
 - 负载均衡
 - 节点熔断
 -  访问限流:部分能力
- 根据请求方法进行限流.
 
 - 配置管理
 - 可观测性
 
可以查看示例
接入配置
在woocoo微服务registry配置节中,指定相应的北极星网格:
polarisRegistry: &polarisRegistry
  name: routing # Optional ,默认为 polaris
  scheme: polaris # 必须指定为polaris
  global: true # Optional 默认为true. 配置是否为全局,如设置true,则上下文为全局.
  ttl: 10s # Optional 心跳时间,[0-60]s, 不设置时, 将使用Polaris默认值.
  polaris:
    # 可以采用配置文件方式.此时内嵌配置无效
    # configFile: etc/polaris.yaml
    # 直接内嵌配置中配置
    global:
      serverConnector:
        addresses:
          - 127.0.0.1:8091
grpc:
  registry:
    <<: *polarisRegistry
    # 配置元数据.
    registryMeta:
      key1: value1
      key2: value2
# 也可以指定为一个独立的配置节,使用独立的配置文件,如下:
grpc2:
  registry:
    <<: *polarisRegistry
client
woocoo微服务中的客户端可以采用标准的GRPC客户端.但更简单的方式是使用woocoo扩展的grpcx.client,不管使用哪种微服务中心,都可以使用该客户端.
配置如下:
grpc:
  registry:
    scheme: polaris
    ttl: 30s # 心跳时间,[0-60]s
    polaris:
      global:
        serverConnector:
          addresses:
            - 127.0.0.1:8091
  client:
    target: # 该节相当于Dial的目标地址信息
      namespace: default # 服务命名空间
      serviceName: helloworld.Greeter # 服务名称
      metadata:        
        route: true # 是否启用动态路由,默认为false
        circuitBreaker: true # 是否启用熔断降级,默认为false
        header_location: amoy #                
客户端的元数据没有使用服务端配置中的registry节点,考虑到客户端使用的元数据与服务端并不一致,因此独立在client.metadata配置节点下,
而polaris区分SrcMetadata及DstMetadata,所以需要在客户端和服务端配置中分别配置.
而在woocoo的Registry组件并未这样区分,因此在metadata中配置前缀来对应,使得可以使用Polaris的治理功能.
在客户端与服务端的通信过程中,grpcx.client会将配置中的metadata作为元数据传递给服务端,服务端可以根据元数据来进行路由,限流等操作.规则如下:
- namespace,serviceName默认传递
 header_前缀的参数在会在对应Polaris中的请求头参数: header_{key}:{value}以 key:value 加入outgoing context.src_前缀的将参与自定义路由.自定义路由是registryMeta中的标签.
如果采用自定义路由时,则其他路由规则将失效.该功能是保持与官方的SDK相同.应该是认为如果采用自定义路由,那自定义的规则就应该足够支持.这是最高性能的方式.
在配置文件中,为固化参数.如果需要使用动态参数,如用户ID,可使用interceptor来实现.
grpcx.client
初始化方式没有特殊点.
client := grpcx.NewClient(app.AppConfiguration().Sub("grpc"))
// 可以传空.
conn, err := client.Dial("")
// 或者
conn, err := client.Dial("polaris://helloworld.Greeter")
原生client
需要指定resolver和负载均衡配置.当然resolver也可以全局注入. 而grpcx.client会自动初始化以支持动态配置.
conn, err := grpc.Dial(scheme+"://routingTest/helloworld.Greeter?route=true",		
			grpc.WithResolvers(&resolverBuilder{}),
			grpc.WithDefaultServiceConfig(`{ "loadBalancingConfig": [{"polaris": {}}] }`),
		)
多集群环境下客户端初始化
在多集群环境下,客户端需要初始化负载均衡器,并在client初始化时指定名称.
grpc:
  registry:
    name: "circuit_breaker"
    scheme: polaris
circuit_breaker:
  # ...其他配置  
程序中使用如下方式:
//   正常初始化
cli := grpcx.NewClient(cnf.Sub("grpc"))
balancer.Register(NewBalancerBuilder("circuit_breaker", GetPolarisContextFromDriver("circuit_breaker")")))
c, err := cli.Dial("", grpc.WithDefaultServiceConfig(`{ "loadBalancingConfig": [{"circuit_breaker": {}}] }`))
原生grpc连接初始化
drv, ok := registry.GetRegistry(scheme)
rb, err := drv.ResolverBuilder(rgcnf)
balancename := "routing"
balancer.Register(NewBalancerBuilder(balancename, GetPolarisContextFromDriver("Registry配置节点ref指向名称")))
conn, err := grpc.Dial(scheme+"://routingTest/helloworld.Greeter?route=true&srcservice=helloworld.Greeter",
    grpc.WithTransportCredentials(insecure.NewCredentials()),
    grpc.WithResolvers(rb),
    grpc.WithDefaultServiceConfig(fmt.Sprint(`{ "loadBalancingConfig": [{"%s": {}}] }`,balancename)),
)