第 36 章 - Go语言 服务网格

服务网格(Service Mesh)是一种管理服务间通信的方法,它允许开发人员对服务之间的交互进行抽象化处理。通过在基础设施层面上实现这一点,服务网格可以帮助解决微服务架构中常见的复杂性和挑战,比如服务发现、负载均衡、加密、认证和授权等。服务网格通常由一系列轻量级网络代理组成,这些代理与应用程序部署在一起,但对应用程序本身是透明的。

服务网格的概念

服务网格的核心思想是在每个服务实例旁边部署一个称为“边车”(sidecar)的小型代理。这些边车代理负责处理服务间的通信,并可以提供额外的功能,如流量管理、安全性和可观测性。服务网格使得开发者可以专注于业务逻辑的编写,而将网络通信的细节交给服务网格来处理。

Istio介绍

Istio 是一个开放源代码的服务网格,它为微服务架构提供了统一的方式来连接、管理和保护微服务。Istio 的设计目的是为了简化服务间的通信、流量管理和安全性。它主要由以下几个部分组成:

  • Pilot:用于服务发现和流量管理。
  • Mixer:用于策略执行和遥测收集。
  • Citadel:用于身份验证和安全。
  • Galley:用于配置管理。

服务网格的使用场景

服务网格适用于需要管理大量微服务的应用程序。以下是几个典型的使用场景:

  • 流量管理:自动路由请求到适当的服务版本,支持蓝绿部署或金丝雀发布。
  • 安全性:提供服务间通信的加密,以及基于角色的访问控制。
  • 可靠性:实现断路器模式以防止故障扩散,提供超时和重试机制以提高系统稳定性。
  • 可观测性:监控服务间的通信,收集日志和指标,帮助快速诊断问题。

结合案例以及源代码详细讲解GO语言的这些内容

假设我们有一个简单的Go应用,它由两个微服务组成:service-aservice-bservice-a 调用 service-b 来获取数据。我们将使用 Istio 来管理这两个服务之间的通信。

1. 创建服务

首先,我们需要创建两个简单的Go服务。这里仅展示 service-a 的基本结构,service-b 类似。

package mainimport ("fmt""net/http""os"
)func handler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Hello from Service A")
}func main() {port := os.Getenv("PORT")if port == "" {port = "8080"}http.HandleFunc("/", handler)fmt.Printf("Starting service on :%s\n", port)http.ListenAndServe(":"+port, nil)
}
2. 配置Istio

接下来,我们需要在Kubernetes上安装Istio,并为我们的服务配置Istio资源。这包括创建一个 VirtualService 来定义如何路由到不同的服务版本,以及一个 DestinationRule 来设置服务的负载均衡策略。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: service-a
spec:hosts:- service-ahttp:- route:- destination:host: service-asubset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: service-a
spec:host: service-asubsets:- name: v1labels:version: v1
3. 部署服务

最后,我们需要将服务部署到Kubernetes集群中,并确保它们被Istio管理。这可以通过在服务的Deployment中添加Istio的边车注入注解来实现。

apiVersion: apps/v1
kind: Deployment
metadata:name: service-alabels:app: service-aversion: v1
spec:replicas: 1selector:matchLabels:app: service-aversion: v1template:metadata:annotations:sidecar.istio.io/inject: "true"labels:app: service-aversion: v1spec:containers:- name: service-aimage: your-docker-repo/service-a:v1ports:- containerPort: 8080

以上就是使用Go语言结合Istio服务网格的一个简单示例。通过这种方式,我们可以更容易地管理和扩展微服务架构中的各个组件,同时利用Istio提供的强大功能来优化服务间的交互。

当然,我们可以进一步深入探讨如何利用Istio来实现更高级的服务网格功能,例如流量管理、安全性和可观测性。以下是一些具体的示例和代码片段,以展示如何在实际项目中应用这些功能。

交通管理

蓝绿部署

蓝绿部署是一种常见的部署策略,可以在不影响现有用户的情况下推出新版本的服务。Istio 通过 VirtualServiceDestinationRule 来实现这一目标。

VirtualService 配置
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: service-a
spec:hosts:- service-ahttp:- route:- destination:host: service-asubset: v1weight: 90- destination:host: service-asubset: v2weight: 10
DestinationRule 配置
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: service-a
spec:host: service-asubsets:- name: v1labels:version: v1- name: v2labels:version: v2

在这个例子中,90% 的流量会被路由到 v1 版本的服务,而 10% 的流量会被路由到 v2 版本的服务。这样可以在不中断服务的情况下逐步测试新版本。

安全性

mTLS (双向 TLS)

Istio 支持自动启用 mTLS,以确保服务间通信的安全性。这可以通过配置 PeerAuthentication 资源来实现。

PeerAuthentication 配置
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:name: defaultnamespace: istio-system
spec:mtls:mode: STRICT

这个配置会强制所有服务之间的通信都使用 mTLS,从而确保数据传输的安全性。

可观测性

监控和日志

Istio 提供了强大的监控和日志功能,可以帮助你更好地了解服务间的通信情况。你可以使用 Prometheus 和 Grafana 来监控服务的性能指标,使用 Fluentd 或 Loki 来收集和分析日志。

Prometheus 和 Grafana 配置

Istio 默认集成了 Prometheus 和 Grafana,你只需要在 Istio 安装时启用这些组件即可。

istioctl install --set profile=demo
日志收集

你可以通过配置 EnvoyFilter 来修改 Envoy 的日志格式,以便更好地满足你的需求。

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: custom-log-formatnamespace: istio-system
spec:workloadSelector:labels:app: service-afilters:- listenerMatch:listenerType: SIDECAR_INBOUNDfilterName: envoy.filters.network.http_connection_managerfilterType: NETWORKpatch:operation: MERGEvalue:typed_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManageraccess_log:- name: envoy.access_loggers.filetyped_config:"@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLogpath: /dev/stdoutlog_format:text_format: "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%UPSTREAM_HOST%\"\n"

这个配置会修改 Envoy 的日志格式,使其包含更多有用的信息,如请求方法、路径、响应时间等。

实际应用案例

假设我们有一个在线商店,包含前端服务、订单服务和库存服务。我们可以使用 Istio 来管理这些服务之间的通信,并实现以下功能:

  1. 流量管理:使用蓝绿部署来逐步推出新版本的前端服务。
  2. 安全性:启用 mTLS 来确保服务间通信的安全性。
  3. 可观测性:使用 Prometheus 和 Grafana 来监控服务的性能,使用 Fluentd 来收集和分析日志。
前端服务
package mainimport ("fmt""net/http""os"
)func handler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Welcome to the Online Store")
}func main() {port := os.Getenv("PORT")if port == "" {port = "8080"}http.HandleFunc("/", handler)fmt.Printf("Starting frontend service on :%s\n", port)http.ListenAndServe(":"+port, nil)
}
订单服务
package mainimport ("fmt""net/http""os"
)func handler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Order placed successfully")
}func main() {port := os.Getenv("PORT")if port == "" {port = "8081"}http.HandleFunc("/", handler)fmt.Printf("Starting order service on :%s\n", port)http.ListenAndServe(":"+port, nil)
}
库存服务
package mainimport ("fmt""net/http""os"
)func handler(w http.ResponseWriter, r *http.Request) {fmt.Fprintf(w, "Inventory checked successfully")
}func main() {port := os.Getenv("PORT")if port == "" {port = "8082"}http.HandleFunc("/", handler)fmt.Printf("Starting inventory service on :%s\n", port)http.ListenAndServe(":"+port, nil)
}
Kubernetes 部署文件
apiVersion: apps/v1
kind: Deployment
metadata:name: frontend-servicelabels:app: frontend
spec:replicas: 1selector:matchLabels:app: frontendtemplate:metadata:annotations:sidecar.istio.io/inject: "true"labels:app: frontendspec:containers:- name: frontendimage: your-docker-repo/frontend-service:v1ports:- containerPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:name: order-servicelabels:app: order
spec:replicas: 1selector:matchLabels:app: ordertemplate:metadata:annotations:sidecar.istio.io/inject: "true"labels:app: orderspec:containers:- name: orderimage: your-docker-repo/order-service:v1ports:- containerPort: 8081
---
apiVersion: apps/v1
kind: Deployment
metadata:name: inventory-servicelabels:app: inventory
spec:replicas: 1selector:matchLabels:app: inventorytemplate:metadata:annotations:sidecar.istio.io/inject: "true"labels:app: inventoryspec:containers:- name: inventoryimage: your-docker-repo/inventory-service:v1ports:- containerPort: 8082

通过以上配置和代码示例,你可以看到如何使用 Go 语言和 Istio 来构建和管理微服务架构。Istio 提供了丰富的功能,可以帮助你更好地管理和优化服务间的通信,提高系统的可靠性和安全性。

好的,我们可以继续深入探讨一些更高级的主题,例如:

  1. 金丝雀发布:逐步将流量从旧版本迁移到新版本。
  2. 故障注入:模拟故障以测试服务的健壮性。
  3. 速率限制:限制服务的请求速率,防止过载。
  4. 熔断器:实现熔断机制以防止故障扩散。
  5. 服务链路追踪:使用 Jaeger 进行分布式追踪,以便更好地理解服务调用链路。

金丝雀发布

金丝雀发布是一种渐进式发布新版本服务的策略,通过将一小部分流量路由到新版本来测试其稳定性和性能。

VirtualService 配置
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: service-a
spec:hosts:- service-ahttp:- route:- destination:host: service-asubset: v1weight: 90- destination:host: service-asubset: v2weight: 10
DestinationRule 配置
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: service-a
spec:host: service-asubsets:- name: v1labels:version: v1- name: v2labels:version: v2

故障注入

故障注入是一种测试服务健壮性的方法,通过模拟网络延迟、超时或错误来验证服务的行为。

VirtualService 配置
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: service-a
spec:hosts:- service-ahttp:- fault:delay:percent: 10fixedDelay: 7sroute:- destination:host: service-asubset: v1

这个配置会在 10% 的请求中注入 7 秒的延迟。

速率限制

速率限制可以防止服务过载,确保系统的稳定性和可用性。

EnvoyFilter 配置
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:name: rate-limitnamespace: istio-system
spec:workloadSelector:labels:app: service-afilters:- listenerMatch:listenerType: SIDECAR_INBOUNDfilterName: envoy.filters.http.ratelimitfilterType: HTTPpatch:operation: ADDvalue:name: envoy.filters.http.ratelimittyped_config:"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimitdomain: "service-a"failure_mode_deny: truerate_limit_service:grpc_service:google_grpc:target_uri: "ratelimit.default.svc.cluster.local"stat_prefix: "rls"transport_api_version: V3

熔断器

熔断器机制可以在检测到服务故障时暂时停止对该服务的请求,以防止故障扩散。

DestinationRule 配置
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:name: service-a
spec:host: service-atrafficPolicy:connectionPool:tcp:maxConnections: 100http:http1MaxPendingRequests: 1http2MaxRequests: 1outlierDetection:consecutiveErrors: 5interval: 1sbaseEjectionTime: 3mmaxEjectionPercent: 10

服务链路追踪

Jaeger 是一个开源的分布式追踪系统,可以与 Istio 集成以提供详细的调用链路信息。

安装 Jaeger
istioctl install --set profile=demo
配置服务以发送追踪数据

在服务中启用 OpenTracing 支持,例如在 service-a 中:

package mainimport ("context""fmt""net/http""os""github.com/opentracing/opentracing-go""github.com/uber/jaeger-client-go"jaegercfg "github.com/uber/jaeger-client-go/config"jaegerlog "github.com/uber/jaeger-client-go/log""github.com/uber/jaeger-lib/metrics"
)func handler(w http.ResponseWriter, r *http.Request) {span := opentracing.SpanFromContext(r.Context())span.LogKV("event", "handler called")fmt.Fprintf(w, "Hello from Service A")
}func main() {port := os.Getenv("PORT")if port == "" {port = "8080"}config := jaegercfg.Configuration{Sampler: &jaegercfg.SamplerConfig{Type:  jaeger.SamplerTypeConst,Param: 1,},Reporter: &jaegercfg.ReporterConfig{LogSpans:            true,LocalAgentHostPort:  "jaeger-agent:6831",},}tracer, closer, err := config.NewTracer(jaegercfg.Logger(jaegerlog.StdLogger),jaegercfg.Metrics(metrics.NullFactory),)if err != nil {panic(err)}defer closer.Close()opentracing.InitGlobalTracer(tracer)http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {ctx := r.Context()parentSpan := opentracing.SpanFromContext(ctx)span := tracer.StartSpan("handleRequest", ext.RPCServerOption(parentSpan))defer span.Finish()newCtx := opentracing.ContextWithSpan(ctx, span)r = r.WithContext(newCtx)handler(w, r)})fmt.Printf("Starting service on :%s\n", port)http.ListenAndServe(":"+port, nil)
}

总结

通过上述配置和代码示例,你可以看到如何使用 Go 语言和 Istio 来实现更高级的服务网格功能。这些功能不仅提高了系统的可靠性和安全性,还增强了系统的可维护性和可观测性。Istio 的强大之处在于它能够无缝集成到现有的微服务架构中,提供了一套完整的解决方案来管理和服务之间的通信。希望这些示例对你有所帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/62064.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【es6】原生js在页面上画矩形及删除的实现方法

画一个矩形,可以选中高亮,删除自己效果的实现,后期会丰富下细节,拖动及拖动调整矩形大小 实现效果 代码实现 class Draw {constructor() {this.x 0this.y 0this.disX 0this.disY 0this.startX 0this.startY 0this.mouseDo…

【前端】JavaScript中的隐式声明及其不良影响分析

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 💯前言💯什么是隐式声明?💯隐式声明的常见情景1. 赋值给未声明的变量2. 非严格模式下的隐式声明3. 函数中的变量漏掉声明4. for 循环中的隐式声明5. 使用…

windows基础之病毒编写

声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&#…

家校通小程序实战教程02口令管理

目录 1 创建数据源2 搭建后台功能3 生成口令4 调用API总结 我们的小程序上线之后,必然面临家长要加入的问题。微搭有登录验证的功能,但是手机验证的机制是,如果你未注册就给你自动注册一个账号,如果以注册了收到验证码就可以登录系…

Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?

大家好,我是锋哥。今天分享关于【Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?】面试题。希望对大家有帮助; Elasticsearch中的节…

阿里发布 EchoMimicV2 :从数字脸扩展到数字人 可以通过图片+音频生成半身动画视频

EchoMimicV2 是由阿里蚂蚁集团推出的开源数字人项目,旨在生成高质量的数字人半身动画视频。以下是该项目的简介: 主要功能: 音频驱动的动画生成:EchoMimicV2 能够使用音频剪辑驱动人物的面部表情和身体动作,实现音频与…

【NLP高频面题 - 分布式训练】ZeRO1、ZeRO2、ZeRO3分别做了哪些优化?

【NLP高频面题 - 分布式训练】ZeRO1、ZeRO2、ZeRO3分别做了哪些优化? 重要性:★★ NLP Github 项目: NLP 项目实践:fasterai/nlp-project-practice 介绍:该仓库围绕着 NLP 任务模型的设计、训练、优化、部署和应用&am…

C#基础控制台程序

11.有一个54的矩阵,要求编程序求出其中值最大的那个元素的值,以及其所在的行号和列号。 12.从键盘输入一行字符,统计其中有多少个单词,单词之间用空格分隔开。 13.输入一个数,判断它是奇数还是偶数,如果…

三六零[601360]行情数据接口

1、三六零:实时行情 Restful API # 测试接口:可以复制到浏览器打开 https://tsanghi.com/api/fin/stock/XSHG/realtime?tokendemo&ticker601360获取股票实时行情(开、高、低、收、量)。 请求方式:GET。 Python示例…

eclipse-git项目提示NO-HEAD

1、出现该问题的过程 本人在用eclipse拉取git代码,刚拉取完,可能还没来得及跟本地的分支合并,电脑就卡动了。无奈只能重启电脑,打开eclipse,maven项目后面就出现了xxx NO-HEAD的提示。 2、问题解决 根据错误提示&am…

Cross-Site Scripting(XSS)攻击

简介 XSS(跨站脚本攻击)是一种常见的 Web 安全漏洞,攻击者通过在目标网站的输入框中注入恶意脚本,当其他用户(如管理员)查看包含恶意脚本的页面时,脚本会在他们的浏览器中执行。XSS 攻击可以分…

uniapp中使用uni-forms实现表单管理,验证表单

前言 uni-forms 是一个用于表单管理的组件。它提供了一种简化和统一的方式来处理表单数据,包括表单验证、字段绑定和提交逻辑等。使用 uni-forms可以方便地创建各种类型的表单,支持数据双向绑定,可以与其他组件及API进行良好的集成。开发者可…

android 11添加切换分屏功能

引言 自Android 7开始官方就支持分屏显示,但没有切换分屏的功能,即交换上下屏幕。直到Android 13开始才支持切换分屏,操作方式是:分屏模式下双击中间分割线就会交换上下屏位置。本文的目的就是在Android 11上实现切换分屏的功能。 下图是Android13切换分屏演示 切换分屏…

springboot项目使用maven打包,第三方jar问题

springboot项目使用maven package打包为可执行jar后,第三方jar会被打包进去吗? 答案是肯定的。做了实验如下: 第三方jar的项目结构及jar包结构如下:(该第三方jar采用的是maven工程,打包为普通jar&#xf…

13 —— 开发环境调错-source map

问题:代码被压缩后,无法正确定位源代码的位置(行数和列数) source map:准确追踪error和warning在原始代码的位置 —— webpack.config.js配置devtool选项 module.exports { devtool: inline-source-map }; inline-s…

数据结构(ArrayList顺序表)

一、引言 1.什么是顺序表 定义: 顺序表是一种基于阵列实现的线性表结构,用连续的存储空间保存表中的数据元素,并按顺序排列。 底层依赖阵列,支持随机访问。元素之间没有额外的连接信息,如指针或链表节点。通过动态扩容…

HTTPS的单向认证和双向认证是什么?有什么区别?

目录标题 单向认证流程双向认证流程区别 单向认证流程 HTTPS单向认证‌是指只有服务器向客户端证明其身份。在这种认证方式中,服务器会向客户端发送一个由可信证书颁发机构(CA)签发的SSL证书,客户端会验证这个证书以确保服务器的…

Python语法基础(一)

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 关键字参数和不定长参数 关键字参数主要体现在函数的调用上 使用关键字参数的好处是,可以不按照形参的参数传参 比如说,我们定义一个函数 def c1(nam…

音视频技术扫盲之预测编码的基本原理探究

预测编码是一种数据压缩技术,广泛应用于图像、视频和音频编码等领域。其基本原理是利用数据的相关性,通过对当前数据的预测和实际值与预测值之间的差值进行编码,从而实现数据压缩的目的。 一、预测编码的基本概念 预测编码主要包括预测器和…

Android BottomNavigationView 底部导航栏使用详解

一、BottomNavigationView简介 BottomNavigationView是官方提供可以实现底部导航的组件,最多支持5个item,主要用于功能模块间的切换,默认会包含动画效果。 官方介绍地址:BottomNavigationView 二、使用BottomNavigationView a…