이 기사는 Founder Securities Financial Technology Engineering Institute의 수석 R&D 엔지니어인 Liu Yi가 "Cloud Native✖️AI 시대의 마이크로서비스 아키텍처 및 기술 실습" CloudWeGo 기술 살롱에서 발표한 "금융 기술 Go 마이크로서비스" 연설을 바탕으로 작성되었습니다. 2024년 3월 30일 베이징에서 열린 베이징 행사. "건설실습"에서 편집.
개요: 이 기사에서는 클라우드 네이티브 마이크로서비스 구축에 대한 Founder Securities Financial Technology Engineering Institute의 실제 경험을 자세히 소개합니다. 공유에는 다음 세 가지 측면이 포함됩니다.
- 마이크로서비스 거버넌스 작업
- 마이크로서비스 관측성 작업
- 위의 마이크로서비스 인터페이스 관리 기능은 Founder의 Quark 개발 플랫폼에 통합되어 있습니다.
파운더증권의 마이크로서비스 구축 실무 소개
2023년 초 등록 센터는 ZooKeeper를 사용 하고 웹 및 RPC 애플리케이션 프레임워크는 각각 CloudWeGo의 Hertz 및 Kitex를 사용하는 마이크로서비스 시스템 구축을 시작했습니다 .
현재 우리는 마이크로서비스 거버넌스 , 관찰성 기능 , 인터페이스 관리 및 기타 관련 작업 을 주로 포함하는 마이크로서비스 구축의 심해 영역에 진입했습니다 . 다음에서는 개념과 구현 원칙을 자세히 소개합니다.
마이크로서비스 거버넌스 역량 구축
개념
마이크로서비스 아키텍처에서는 비즈니스 규모가 점차 증가함에 따라 서비스 수도 점차 증가합니다. 이러한 배경을 바탕으로 비즈니스가 발전함에 따라 서비스를 관리하고 통제하는 것이 점점 더 어려워질 것입니다. 서비스 거버넌스의 역할은 서비스 분할로 인해 발생하는 일련의 문제를 해결하여 서비스가 보다 안정적으로 운영될 수 있도록 하는 것입니다. 서비스 등록 및 검색, 로드 밸런싱, 서비스 회로 차단기, 서비스 저하, 서비스 전류 제한 등을 제공합니다. Quark 플랫폼에서 제공하는 타임아웃, 재시도 및 서버 측 전류 제한 기능은 모두 Kitex 의 관련 기능을 기반으로 합니다 . 현재 사용되는 등록 센터는 ZooKeeper(약칭 zk)이므로 관련 동적 구성도 도움말을 통해 구현됩니다. zk의 구성을 zk에 작성하여 서버와 클라이언트에 관련 기능의 활성화를 완료하도록 알립니다.
소개하다
-
흐름 제어
흐름 제어의 세분성은 서비스 수준입니다. 아래 그림에 표시된 것처럼 서비스는 초당 최대 1,000개의 요청을 처리할 수 있으며 과도한 요청은 직접 종료됩니다.
-
구성 재시도
재시도 구성의 세분성은 현재 서비스가 지정된 서비스의 메서드에 대한 요청을 만드는 데 실패할 때 재시도 방법을 구성하는 데 사용되는 메서드 수준입니다.
-
시간 초과 구성
시간 제한 구성의 세분성은 현재 서비스가 지정된 서비스의 메서드를 요청하는 데 걸리는 최대 시간을 구성하는 데 사용되는 메서드 수준에 있습니다. 이 값이 초과되면 현재 서비스의 연결이 끊어집니다. 구성을 참조하세요. 각 구성의 특정 기능에 대한 설명입니다.
구현 원칙 및 세부 사항
서버 측과 클라이언트 측 모두 Kitex 제품군을 확장하여 관련 구성의 동적 주입을 완료합니다 .
서버 측
다음 코드를 통해 Kitex 서버를 구성하십시오.
server.WithSuite(zooKeeperServer.NewSuite("Kitex-server", zooKeeperClient))
그중에는 zooKeeperServer.NewSuite("Kitex-server", zooKeeperClient)
Suite 인스턴스가 반환되며 서버에 주입된 리미터 구성이 포함됩니다. Options
func (s *zooKeeperServerSuite) Options() []server.Option {
opts := make([]server.Option, 0, 2)
// WithLimiter实现中,在zk中注册了监听器,每当数据变化,动态更新Limiter的相关配置,以达到限流目的
opts = append(opts, WithLimiter(s.service, s.zooKeeperClient, s.opts))
return opts
}
위 내용을 바탕으로, 서버측 제품군에서는 기본적으로 리미터만 구성되어 있음을 알 수 있습니다. Kitex 프레임워크는 현재 두 가지 유형의 리미터만 지원합니다.
- 연결 제한기(최대 연결 수 제한)
- Qps 제한기(최대 qps 제한)
zk를 등록 센터로 사용하면 둘 다 구성을 통해 동적으로 조정될 수 있으며, 구성 값은 zk의 리스너를 통해 얻을 수 있습니다.
// zk数据变化时的回调方法
onChangeCallback := func(restoreDefault bool, data string, parser zooKeeper.ConfigParser) {
lc := &limiter.LimiterConfig{}
if !restoreDefault && data != "" {
err := parser.Decode(data, lc)
if err != nil {
klog.Warnf("[zooKeeper] %s server zooKeeper config: unmarshal data %s failed: %s, skip...", dest, data, err)
return
}
}
// 将zk中的数据动态更新到配置中
opt.MaxConnections = int(lc.ConnectionLimit)
opt.MaxQPS = int(lc.QPSLimit)
u := updater.Load()
if u == nil {
klog.Warnf("[zooKeeper] %s server zooKeeper limiter config failed as the updater is empty", dest)
return
}
if !u.(limit.Updater).UpdateLimit(opt) {
klog.Warnf("[zooKeeper] %s server zooKeeper limiter config: data %s may do not take affect", dest, data)
}
}
// path,对于limiter,其值为:/KitexConfig/{ServiceName}/limit
zooKeeperClient.RegisterConfigCallback(context.Background(), path, uniqueID, onChangeCallback)
고객 입장에서
서버 측과 마찬가지로 클라이언트 측에도 동일한 구성이 있습니다.
bizService.NewClient("Kitex-client",
client.WithSuite(zooKeeperclient.NewSuite("Kitex-server", "Kitex-client", zooKeeperClient)))
클라이언트 측 제품군에는 다음 옵션이 포함되어 있습니다.
func (s *zooKeeperClientSuite) Options() []client.Option {
opts := make([]client.Option, 0, 7)
opts = append(opts, WithRetryPolicy(s.service, s.client, s.zooKeeperClient, s.opts)...)
opts = append(opts, WithRPCTimeout(s.service, s.client, s.zooKeeperClient, s.opts)...)
opts = append(opts, WithCircuitBreaker(s.service, s.client, s.zooKeeperClient, s.opts)...)
return opts
}
즉, 클라이언트는 재시도, 시간 초과 및 회로 차단기라는 세 가지 동적 구성을 지원합니다. 관련 처리는 zk 클라이언트의 콜백 메소드를 통해 수행되어 동적 업데이트 효과를 얻습니다.
시간 초과 구성에 대한 추가 참고 사항
시간 초과의 경우 구성 방법의 구체적인 구현은 다음과 같습니다.
func WithRPCTimeout(dest, src string, zooKeeperClient zooKeeper.Client, opts utils.Options) []client.Option {
// ...
return []client.Option{
client.WithTimeoutProvider(initRPCTimeoutContainer(path, uid, dest, zooKeeperClient)),
client.WithCloseCallbacks(func() error {
// cancel the configuration listener when client is closed.
zooKeeperClient.DeregisterConfig(path, uid)
return nil
}),
}
}
마지막으로 Kitex에서 제공하는 메소드를 호출하여 client.WithTimeoutProvider
timeout과 관련된 특정 구성을 완료합니다 . 시간 초과의 경우 다음과 같은 다양한 구성 방법이 있습니다.
func WithRPCTimeout(d time.Duration) Option {
// ...
}
func WithConnectTimeout(d time.Duration) Option {
// ...
}
func WithTimeoutProvider(p rpcinfo.TimeoutProvider) Option {
// ...
}
그 중 WithTimeoutProvider
설정된 시간 제한은 설정된 값 WithRPCTimeout
으로 덮어쓰기 되므로 Kitex 클라이언트 생성 시 또는 WithConnectTimeout
가 호출되면 동적 구성이 적용되지 않습니다.WithRPCTimeout
WithConnectTimeout
구성 지침
타임아웃
해당 zk 노드:/kitexConfig/{ClientName}/{ServiceName}/rpc_timeout
작성된 구성 형식은 다음과 같습니다.
{
"*": {
"conn_timeout_ms": 100,
"rpc_timeout_ms": 800
},
"GetDemoInfo": {
"rpc_timeout_ms": 300
},
"GetDemoInfo3": {
"rpc_timeout_ms": 300
}
}
필드 의미 : 새로운 연결을 설정하기 위한 최대 대기 시간 : rpc 호출을 위한 최대 시간. conn_timeout_ms
rpc_timeout_ms
다시 해 보다
해당 zk 노드:/kitexConfig/{ClientName}/{ServiceName}/retry
작성된 구성 형식은 다음과 같습니다.
{
"GetDemoInfo": {
"enable": true,
"type": 0,
"failure_policy": {
"stop_policy": {
"max_retry_times": 2,
"max_duration_ms": 9000,
"cb_policy": {
"error_rate": 0.1
}
}
}
},
"GetDemoInfo5": {
"enable": true,
"type": 0,
"failure_policy": {
"stop_policy": {
"max_retry_times": 2,
"max_duration_ms": 9000,
"cb_policy": {
"error_rate": 0.1
}
}
}
}
}
필드 의미
구성 항목 | 기본값 | 설명하다 | 한계 |
---|---|---|---|
max_retry_times | 2 | 첫 번째 요청을 제외한 최대 재시도 횟수입니다. 0으로 설정하면 재시도를 중지한다는 의미입니다. | 유효한 값: [0-5] |
max_duration_ms | 0 | 첫 번째 실패한 요청 및 재시도 요청에 대한 경과 시간을 포함하여 경과된 최대 누적 시간입니다. 경과 시간이 한도에 도달하면 후속 재시도가 중지됩니다. 0은 제한이 없음을 의미합니다. 참고: 구성된 경우 이 구성 항목은 요청 제한 시간보다 커야 합니다. | |
오류율 | 10% | 회로 차단기 오류율 임계값 재시도. 메서드 수준 요청 오류율이 임계값을 초과하면 재시도가 중지됩니다. | 법적 가치: (0-30%] |
제한
이 구성은 서비스에 대한 전역 구성이므로 zk 노드 경로에는 serviceName만 포함됩니다./kitexConfig/{ServiceName}/limit
작성된 구성 형식은 다음과 같습니다.
{
"qps_limit": 100
}
마이크로서비스 관측성 역량 구축
개념
서비스 관찰 가능성 구축은 시스템의 운영 상태와 성능 지표를 포괄적이고 시기적절하게 이해하기 위해 분산 시스템에서 모니터링, 로깅, 추적 및 기타 도구와 기술을 구축하고 개선하는 것을 의미합니다.
완전한 관찰 도구는 비즈니스 시스템에 많은 이점을 가져올 수 있습니다.
- 적시에 문제를 감지하고 해결하는 능력;
- 팀이 시스템의 전반적인 운영과 내부 상호 작용을 보다 명확하게 이해할 수 있도록 합니다.
- 용량 계획 및 리소스 최적화를 지원하기 위해 시스템의 로드 상태, 리소스 활용도 및 추세 변화를 이해할 수 있습니다.
- 시스템의 운영 로그와 요청 추적을 로그 및 추적 시스템을 통해 기록함으로써 사용자의 운영 행위, 비정상적인 요청 및 보안 이벤트를 추적하고 분석하여 시스템의 보안성과 신뢰성을 향상시킬 수 있습니다.
소개하다
서비스 세부 정보는 골든 모니터링 지표(QPS, 지연 시간 및 오류 비율), SLO 및 런타임 관련 정보 등을 포함하여 서비스 자체의 전반적인 운영을 표시하는 데 사용됩니다.
토폴로지 다이어그램은 서비스 간의 업스트림 및 다운스트림 종속성을 표시하는 데 사용됩니다.
콜 체인 데이터에는 서비스 간 각 호출에 대한 자세한 정보가 포함되어 있습니다.
구현 원칙 및 세부 사항
현재 OpenTelemetry 클라이언트는 템플릿 코드에 통합되었으며 생성된 Hertz 및 Kitex 서비스에는 기본적으로 관찰 가능한 데이터(메트릭 + 추적) 보고 기능이 있습니다.
자세한 내용은 kitex-contrib/obs-opentelemetry 및 hertz-contrib/obs-opentelemetry를 참조하세요.
OpenTelemetry (OTel)는 개발 팀이 통합된 단일 형식으로 원격 측정 데이터를 생성, 처리 및 전송할 수 있는 오픈 소스 관찰 프레임워크입니다. 이는 측정항목, 로그 및 추적을 수집하여 모니터링 플랫폼으로 전송하기 위한 표준 프로토콜과 도구를 제공하기 위해 CNCF(Cloud Native Computing Foundation)에서 개발되었습니다. OpenTelemetry는 공급업체에 독립적인 SDK, API 및 도구를 제공합니다. OpenTelemetry는 클라우드 네이티브 애플리케이션을 위한 주요 관찰성 원격 측정 데이터 표준으로 빠르게 자리잡고 있습니다. OpenTelemetry를 채택하는 것은 특정 공급업체에 얽매이거나 레거시 기술의 제한을 받지 않고 미래의 데이터 요구 사항을 충족할 준비를 원하는 조직에 매우 중요합니다.
추적하다
추적은 요청 수신부터 완료까지 전체 수명 주기에 대한 완전한 그림을 제공합니다.
요청을 받은 후 서비스는 메타 정보(Kitex) 또는 http 헤더(Hertz)에서 링크 추적을 활성화합니다. 메타 정보나 HTTP 헤더에 추적 정보가 없으면 새 링크 추적이 자동으로 활성화됩니다. 링크 정보는 컨텍스트를 통해 서비스 프로세스 내에서 전달됩니다.
액세스 방법:
// for Hertz
tracer, cfg := hertztracing.NewServerTracer()
h := server.Default(tracer)
h.Use(hertztracing.ServerMiddleware(cfg))
// for Kitex
svr := echo.NewServer(new(DemoImpl),
server.WithSuite(tracing.NewServerSuite()),
server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: serviceName}),)
추적 정보는 OpenTelemetry Collector에 보고된 후 Jaeger에 투명하게 전송됩니다. 링크 관련 정보는 Jaeger에서 조회할 수 있습니다.
기본적으로 추적 관련 정보를 인쇄하는 통합 로그 프린터 fzlog를 제공합니다.
{
"file": "get_repositories.go:33",
"func": "gitlab.fzzqft.com/ifte-quark/quark-api/biz/service.(*GetRepositoriesService).Run",
"level": "info",
"msg": "GetRepositoriesService Run req: page:1 limit:10 service_name:\"kitex\"",
"span_id": "aa26bab58cdf6806",
"time": "2024-04-23 15:59:40.609",
"trace_flags": "01",
"trace_id": "f714dbe2a96b1882dfc4b81909e55643"
}
로그를 수집하고 처리한 후 로그 플랫폼에서 전체 링크의 관련 로그 정보를 조회할 수 있습니다. trace_id
측정항목
메트릭은 요청률, 응답 시간, 오류율 등과 같은 시스템 성능 및 동작을 측정하는 핵심 데이터입니다. 메트릭은 일반적으로 시스템 상태를 모니터링하고 추세 분석을 수행하기 위해 수집, 집계 및 시각화됩니다.
현재 각 서비스는 자체 Metrics 데이터를 보고하고 이를 Prometheus/VictoriaMetrics에 균일하게 저장하며 마지막으로 grafana를 사용하여 모니터링 패널을 구성합니다.
다음은 QPS, 요청 시간, 오류율이라는 세 가지 일반적인 서비스 설명 지표를 사용하여 서비스에서 보고한 지표 데이터를 사용하는 방법을 보여줍니다.
-
QPS: QPS 정의에 따라 실시간 요청 수만 확보하면 QPS를 계산할 수 있습니다.
http_server_duration_count
보고된 데이터의 값은 요청 수와 일치하므로 이 지표를 사용하여 QPS 계산을 완료할 수 있습니다. QPS.sum(rate(http_server_duration_count{service_name="$service_name"}[$__rate_interval]))
복사위의 promQL에서는 rate 함수를 사용하여 지정된 기간 내 특정 지표의 증가율을 계산하고, 최종 결과는 지정된 기간 내 평균 요청 수입니다.
-
요청 시간 소비: 통계 데이터이므로 여기서는 평균을 사용하여 서비스 요청의 시간 소비를 나타냅니다. 평균 시간 소비는 지정된 기간 동안 모든 요청의 총 시간 소비로 구됩니다. 지정된 기간의 요청:
sum(rate(http_server_duration_sum{service_name="$service_name"}[$__rate_interval])) by (application) / sum(rate(http_server_duration_count{service_name="$service_name"}[$__rate_interval])) by (application)
복사 -
오류율: 먼저 오류가 발생한 요청 수를 필터링하고 총 요청 수로 나누어 오류율을 구합니다.
round((1 - (sum(rate(http_server_duration_count{service_name="$service_name",http_status_code=~"^(2|3).*"} [$__interval]))/sum(rate(http_server_duration_count{service_name="$service_name"}[$__interval])))), 0.0001)
복사
토폴로지
전체 서비스 간 종속성은 Aggregation에 언급된 Metric 데이터를 통해 표시되며, 보고된 데이터에는 정보가 포함되어 있으며 service_name
, source
서비스 의 업스트림 및 다운스트림 정보는 target
PromSQL 연산자를 통해 얻을 수 있습니다.sum
마이크로서비스 인터페이스 관리 역량 구축
개념
-
IDL
IDL(인터페이스 설명 언어)은 소프트웨어 구성 요소의 인터페이스를 설명하는 데 사용되는 컴퓨터 언어입니다. IDL은 프로그래밍 언어 독립적인 방식으로 인터페이스를 설명하여 서로 다른 플랫폼에서 실행되는 개체와 서로 다른 언어로 작성된 프로그램이 서로 통신할 수 있도록 합니다.
-
인터페이스 관리
Kitex(RPC) 서비스는 모두 IDL을 기반으로 구현됩니다. 인터페이스 관리 플랫폼은 주로 RPC 서비스의 IDL 제품을 관리하기 위한 인터페이스 플랫폼을 제공하므로 개발자가 RPC 인터페이스를 보다 쉽게 관리하고 호출할 수 있습니다.
-
인터페이스 테스트
Kitex(RPC) 서비스는 테스트할 수 없습니다. 인터페이스 테스트 플랫폼 사용자는 디버깅을 완료하기 위해 플랫폼을 통해 RPC 요청을 시작하여 테스트 및 개발을 용이하게 하기 위해 이 문제를 해결합니다.
소개하다
- 인터페이스 관리 플랫폼(작동 방법은 사진 참조)
- 인터페이스 테스트 플랫폼(Kitex(RPC) 인터페이스 디버깅)
구현 원칙 및 세부 사항
-
인터페이스 관리
이전에는 Kitex 서비스 의 IDL 제품을 관리하기 위해 gitlabci가 있는 독립 창고를 사용했는데 , 실제 사용 중에 다음과 같은 문제점이 있었습니다.
- 발신자는 작은 창(비공개 채팅)을 통해 IDL 제품 창고의 주소, 지점 또는 버전 번호를 얻어야 합니다.
- 서비스 제공 방법은 서비스 프로젝트 창고와 해당 제품 창고 모두에 주의를 기울여야 합니다.
- Gitlabci는 러너에 크게 의존하며 새 그룹을 사용하려면 관리자가 구성해야 합니다.
- 기존 CICD 프로세스에 깊이 바인딩할 수 없음
위와 같은 문제점과 Pain Point를 해결하기 위해 인터페이스 관리 플랫폼을 설계하고 개발하였다.
서비스가 구축되고 패키징되면 플랫폼은 자동으로 서비스 유형을 감지하고 해당 IDL 제품을 생성하여 gitlab 독립 창고에 제출합니다. 사용자는 플랫폼에서 IDL 제품을 수동으로 생성하거나 업데이트할 수도 있습니다. 호출자는 해당 버전의 서비스 종속성을 얻으려면 import path 명령을 복사하고 실행하기만 하면 됩니다.
-
인터페이스 테스트는 Kitex PB의 JSON 매핑 일반화 호출을 기반으로 구현됩니다. 사용자는 플랫폼에서 해당 서비스와 인터페이스를 선택하고, 플랫폼은 해당 IDL 파일을 자동으로 구문 분석하고 기본 요청 매개변수(json 형식)를 제공합니다. 요청을 보낸 후 플랫폼은 일반화된 호출을 통해 대상 서비스에 대한 RPC 요청을 시작하고 결과를 반환합니다.
요약
현재의 마이크로서비스 시스템은 이미 대부분의 기술적 요구 사항을 충족할 수 있지만, 우리는 클라우드 네이티브 시스템으로 더욱 발전할 계획입니다.
- 서비스 거버넌스는 클라우드 네이티브 서비스 메시(ServiceMesh) 기능을 사용하여 트래픽을 관리하는 동시에 다른 애플리케이션 프레임워크의 동서 트래픽을 통합합니다.
- Observability인 OpenTelemetry는 언어 및 애플리케이션 프레임워크에 독립적인 솔루션 세트로, 통합된 의미론을 통해 Java의 웹(Springboot) 및 RPC(Dubbo) 시스템을 통합할 계획입니다.
- 인터페이스 관리, 향후에는 RPC 및 HTTP 인터페이스를 통합 관리하고 인터페이스 사용 사례를 자동으로 생성할 계획입니다.
최근 활동
기업 사용자와 개발자는 CloudWeGo Technology Salon 에 참여하도록 진심으로 초대됩니다 . 이 행사는 2024년 5월 25일 ( 토요일) 상하이에서 개최되며 , 기술 동료를 초대하여 기업이 클라우드 네이티브 xAI 의 물결 속에서 빠른 반복과 제품 개발을 지원하기 위해 클라우드 네이티브 마이크로서비스 아키텍처를 구축할 수 있는 방법에 대해 논의합니다. 사진 속 QR코드를 스캔하시면 바로 가입하실 수 있습니다. 거기서 만나요!
"Celebrateing More Than Years 2"의 불법 복제 리소스가 npm에 업로드되어 npmmirror가 unpkg 서비스 를 중단해야 했습니다. Microsoft의 중국 AI 팀은 수백 명의 사람들을 모아 미국으로 떠났습니다. 프론트엔드 시각화 라이브러리와 Baidu의 유명한 오픈 소스 프로젝트 ECharts - Fish 사기꾼을 지원하기 위한 "going to the sea"는 TeamViewer를 사용하여 398만 개를 전송했습니다! 원격 데스크톱 공급업체는 무엇을 해야 합니까? Zhou Hongyi: Google은 시간이 얼마 남지 않았습니다. 모든 제품을 오픈소스로 만드는 것이 좋습니다. 한 유명 오픈소스 회사의 전직 직원이 소식을 전했습니다. 부하 직원의 도전을 받은 후 기술 리더는 분노했습니다. Google은 Android 가상 머신에서 ChromeOS를 실행하는 방법을 보여주었습니다. 여기서 time.sleep(6)은 어떤 역할을 합니까? 마이크로소프트, 중국 AI 팀이 "미국을 위해 준비 중"이라는 루머에 대응 사무용 소프트웨어의 마트료시카 같은 충전에 대한 인민일보 온라인 논평: "세트"를 적극적으로 해결해야만 미래를 가질 수 있다