gRPC服務發現與服務治理技術選型

[原創文章,轉載請標明出處,謝謝!]

gRPC服務發現與服務治理,目前常看法決方案有如下兩種node

  • Nginx + consul + consul-template
  • Envoy

本文粗略講解一下兩種方案的優缺點nginx

一. nginx + consul + consul-template

實現步驟

  1. grpc微服務註冊到consul, consul會定時發送心跳到grcp微服務
  2. 當consul節點有更新時, consul-template生成nginx-consul.conf文件
  3. nginx reload完成服務更新, 當有請求時upstream轉發到grpc微服務

nginx-consul.conf大體以下golang

# nginx須要安裝grpc模塊
upstream User {
    server 127.0.0.1:17000;
    server 127.0.0.1:18000;
}
server {
    listen       19000 http2;
    server_name  _;
    
    location /protobuf.User {
        default_type application/grpc;
        grpc_pass grpc://User;
    }
}	
複製代碼

優勢

  1. 簡單易用,文檔豐富

缺點

  1. consul心跳只是以ping tcp端口爲標準, 沒法肯定服務是否正常響應
  2. 當有節點上線或下線時, 須要nginx reload. 有必定風險 (微服務在運行時不免會觸發隱藏Bug或者panic, 若是每次都要nginx reload來確保健康的路由,我認爲代價太大)

二.Envoy

Envoy 是專爲大型現代 SOA(面向服務架構)架構設計的 L7 代理和通訊總線。是istio重要組件之一
bash

你們都發現這個圖裏面少了consul註冊中心, 是否是意味使用Envoy就不須要註冊中心? 答案是看狀況而定
由於Envoy支持動態配置,因此Istio中是搭配pilot使用, pilot能夠經過consul,etcd等註冊中心獲取在線節點, 而後動態註冊到Envoy.

envoy.yaml架構

node:
  id: id_1
  cluster: test_cluster

watchdog:
  miss_timeout: 0.2s
  megamiss_timeout: 1s
  kill_timeout: 0s
  multikill_timeout: 0s

admin:
  access_log_path: /var/log/admin_access.log
  address:
    socket_address: { address: 127.0.0.1, port_value: 10000 }

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 127.0.0.1, port_value: 19000 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          stat_prefix: ingress_http
          codec_type: HTTP2
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match: { prefix: "/protobuf.User" }
                route: { cluster: xds_cluster }
          http_filters:
          - name: envoy.router
  clusters:
  - name: xds_cluster
    connect_timeout: { seconds: 1 }
    type: STATIC
    lb_policy: ROUND_ROBIN
    http2_protocol_options: {}
    hosts:
    - socket_address: { address: 127.0.0.1, port_value: 18000 }
    - socket_address: { address: 127.0.0.1, port_value: 17000 }
    health_checks:
    - grpc_health_check: {service_name: YourServiceName}
      unhealthy_threshold : 1
      healthy_threshold: 1
      timeout: 0.5s
      interval: 0.5s
      interval_jitter: 0.5s
複製代碼

這是一個靜態的路由配置,帶grpc健康檢查, 有四個關鍵點app

  1. listeners : 監聽127.0.0.1:19000
  2. filters : 過濾grpc請求,路由到xds_cluster
  3. clusters : 由hosts組成的集羣
  4. health_checks: grpc健康檢查

如何實現grpc健康檢查

# 引入protobuf包google.golang.org/grpc/health/grpc_health_v1並實現裏面的Check和Watch方法
package health
import(
	"log"
	"context"
	pb "google.golang.org/grpc/health/grpc_health_v1"
)
type Health struct{}
func New() *Health {
	return &Health{}
}
func (h *Health) Check(ctx context.Context, in *pb.HealthCheckRequest) (*pb.HealthCheckResponse, error){
	log.Printf("checking............%s", in.Service)
	var s pb.HealthCheckResponse_ServingStatus = 1
	return &pb.HealthCheckResponse{
		Status : s,
	}, nil
}
func (h *Health) Watch(in *pb.HealthCheckRequest, w pb.Health_WatchServer) (error){
	log.Printf("watching............%s", in.Service)
	var s pb.HealthCheckResponse_ServingStatus = 1
	r := &pb.HealthCheckResponse{
		Status : s,
	}
	for {
		w.Send(r)
	}
	return nil
}
複製代碼
# 服務註冊
pb.RegisterHealthServer(grpcServer, health.New())
複製代碼

啓動envoy和grpc服務後, grpc就會收心跳(默認的心跳是60秒,yaml的心跳設置是0.5秒)
YourServiceName就是yaml中grpc_health_check的service_name參數,這裏你能夠自定義你想監聽的方法dom

優勢

  1. 輕量級,無侵入式.服務發現由envoy主動發現,grpc不須要特定配置,
  2. 自帶grpc健康檢查
  3. 動態配置

缺點

  1. 相關中文文檔比較少

總結

相對於nginx, 我更傾向於envoy,首先envoy就是爲微服務而生的負載勻衡工具. grpc健康檢查是微服務中重要的一環. 可是nginx擁有活躍的社區,說不定不久未來也會有支持grpc健康檢查的插件.socket

相關文章
相關標籤/搜索