微服务边车模式深度解析:赋能云原生应用的终极指南(自己搞一个简单SideCar?)

什么是SideCar?

file

Sidecar模式定义:

Sidecar 模式是一种常用于微服务架构中的设计模式,该模式允许将应用程序的核心功能与辅助功能(如日志记录、监控、配置管理、网络通信等)分离开来。在这种设计模式中,每个微服务主容器旁边都有一个“边车”(Sidecar)容器运行辅助功能,就像摩托车旁的边车一样,Sidecar 容器和主容器共享同一个生命周期和网络空间。

你专心开车,其他交给我。

file

整体Sidecar就是这样:

file

总结:把非核心业务杂七杂八的东西分离出来,微服务的关注点尽可能只在业务上面,减少业务开发的复杂度。

Sidecar主要干啥?

Sidecar模式通常会处理以下范围的功能:

  1. 网络通信

    • 代理和管理微服务之间的通信,例如用来处理进出的网络流量、服务发现、负载均衡、断路、重试和超时。
  2. 安全性

    • 实现安全协议,如TLS加密、认证、授权和密钥管理。
  3. 监控与日志记录

    • 收集和导出日志、性能度量指标和追踪信息,以供监控系统使用。
  4. 配置管理

    • 动态加载和管理配置数据,而无需重启应用程序。
  5. 故障处理和调试

    • 提供调试支持,记录崩溃报告和性能瓶颈。
  6. 健康检查

    • 周期性地检查主服务的健康,并可实施自我修复措施。
  7. API 网关或接口转换

    • 处理服务的REST或gRPC API,提供API网关功能,或者对老旧系统进行接口转换。
  8. 服务依赖抽象

    • 管理服务间的数据库连接、队列等系统资源的访问。
  9. 请求/响应转换

    • 对进出的请求或响应数据进行转换或扩展。

Sidecar有哪些实现?

Sidecar在容器化和微服务领域有很多实现:

1. Envoy

Envoy是一个开源的、高性能的边缘和服务代理,专门设计用于云原生应用环境。由Lyft公司首次开发发布,后来成为了Cloud Native Computing Foundation(CNCF)的一部分。它的设计允许它同时在应用程序的边缘和内部使用,作为边缘网关、负载均衡器或服务网格的一部分,以提高微服务之间的通信质量和效率。

file

  1. Istio
    Istio是一个开源的服务网格,用于连接、保护、控制和观察在Kubernetes集群中运行的服务。它为微服务提供一种统一的方式来管理网络通信,安全性,策略和观察性,无需改变应用本身的代码。Istio利用了Envoy代理,它作为Sidecar部署在每个服务的Pod中,拦截所有进出Pod的网络通信。
     

    file

    file

  2. Linkerd
    Linkerd是一个开源的服务网格,专门为云原生应用设计,用以在微服务架构中提供可靠的服务间通信。它提供关键功能,如服务发现、负载均衡、故障处理、请求路由和安全性,在不改动服务代码的情况下,使得服务更容易监控、管理和控制。Linkerd是由Buoyant公司开源的,并且是Cloud Native Computing Foundation(CNCF)的一部分。

    file

自己搞一个简单的?

我们个人势单力薄,搞一个像他们这么有高级功能的组件还是挺费时间的,况且我们还在温饱线上挣扎。

但是又想在这块搞点小事情,那么整个简单的。

先来个简单的需求

一个业务系统部署在k8s集群中,每个服务采用一个Pod一个服务的方式部署,每个Pod都有一个Service。

file


就这么简单来一下就可以了,Service关联Pod提供统一访问入口。

那根据SideCar的拓扑,我们可以在Service和Pod中容器之间加一个Sidecar来管理流量,像这样:

file

在这个拓扑中,所有流量先进SVC(逻辑上哈),然后转发给车最后转发给Pod。

车的具体需求?

  1. 管理HTTP流量(TCP的暂时不支持):只开发一个IP白名单规则。如果请求这个服务的IP不在这个白名单中,则返回404,否则转发该请求。
  2. 白名单规则配置:支持单个IP地址,支持CIDR地址。

需求就是这么简单,我们让SVC把流量先转给车,车处理了一下以后再转发给业务服务。

准备开干

首先开发一个HTTP服务器

使用Go built-in API就可以很简单开发实现一个HTTP服务器,就是使用net包:

http.HandleFunc("/", handler)err = http.ListenAndServe(conf.Server.Addr, nil)if err != nil {log.Fatal("ListenAndServe: ", err)}

COPY

几行代码搞定,额,这还是有点快,让人猝不及防。那这样我们的HTTP服务器就搞定了

其次 读取配置文件

我们用yaml来定义白名单配置,白名单中有IP和CIDR地址。


whitelist:- 192.168.1.1- 192.168.1.2- 10.22.81.0/24- ::1

COPY

然后我们使用yaml解析库来读取它。

先来下载一下依赖库:


go get gopkg.in/yaml.v2

COPY

然后使用库提供的api来读取yaml文件:


type Conf struct {Server     Server     `yaml:"server"`Downstream Downstream `yaml:"downstream"`Whitelist  []string   `yaml:"whitelist"`
}err = yaml.Unmarshal(source, &conf)if err != nil {log.Panic(err)}

COPY

设置HTTP的请求处理函数

我们请求处理函数从X-FORWARDED-FOR协议头来获取请求的Ip列表字符串,字符串以ip1,ip2,ip3,...来组成的。

我们只取第一个,就是上面示例的ip1,因为只有这个IP才表示请求方的IP,其他都是代理方的。

func handler(w http.ResponseWriter, r *http.Request) {ipStr := r.Header.Get("X-FORWARDED-FOR")if ipStr == "" {ipStr = strings.Split(r.RemoteAddr, ":")[0]} else {ipStr = strings.TrimSpace(strings.Split(ipStr, ",")[0])}// 如果IP地址在白名单中,那么就转发请求if ipInWhitelist(ipStr, conf.Whitelist) {serveReverseProxy(conf.Downstream.URL, w, r)return}// 否则返回404http.NotFound(w, r)
}

COPY

转发请求

Go内建包net实现了ReverseProxy,我们直接使用httputil.NewSingleHostReverseProxy就可以直接转发HTTP请求,很快~。


func serveReverseProxy(target string, w http.ResponseWriter, r *http.Request) {url, _ := url.Parse(target)proxy := httputil.NewSingleHostReverseProxy(url)r.URL.Host = url.Hostr.URL.Scheme = url.Schemer.Header.Set("X-Forwarded-Host", r.Header.Get("Host"))r.Host = url.Hostproxy.ServeHTTP(w, r)
}

COPY

这样我们的核心功能就实现了。

一点小细节

实现了核心流程以后,我们还得关注配置中IP的解析。
Go的net 包也提供了IP地址和CIDR地址的解析,我们只需要调用一下

  1. net.ParseIP
  2. net.ParseCIDR
    就可以实现IP解析了。

transformToCIDR 这个函数就给IP地址增加/32转换成CIDR形式,大家可以不用太关注。


func ipInWhitelist(ipStr string, whitelist []string) bool {ip := net.ParseIP(ipStr)for _, cidr := range whitelist {_, ipNet, err := net.ParseCIDR(transformToCIDR(cidr))if err != nil {return false}if ipNet.Contains(ip) {return true}}return false
}

COPY

部署

开发这个简单的需求一百多行代码就可以搞定了,但是部署怎么办?

我们在k8s中不是有Service嘛,我们Service在配置流量转发规则的时候先转到我们的HTTP Server,然后我们HTTP再转发给业务服务。

Pod改造

原来我们的拓扑是这样的:

file

加上我们自己的sidecar就变成这样了:

file

随之而来的改造

k8s Pod支持一个Pod多个Container,所以我们可以直接在Pod中增加一个Container:
比如:原来我们的Pod定义是这样的:

- name: my-order-appimage: my-registry-domain-name/ my-order-app:${my-order-app-version}imagePullPolicy: IfNotPresentports:- containerPort: 8080

COPY

改造后:

containers:- name: sidecarimage: my-registry-domain-name/my-custom-sidecar:latestimagePullPolicy: Alwaysports:- containerPort: 8081- name: my-order-appimage: my-registry-domain-name/ my-order-app:${my-order-app-version}imagePullPolicy: IfNotPresentports:- containerPort: 8080

COPY

Pod的改造就完成了,接下来就是Service改造了。

Service改造

我们要把Service的目标端口改成我们自己的Sidecar应用才可以。

比如:原来我们的Service是这样的:
Service端口为8080,转发到app的8080端口中。


apiVersion: v1
kind: Service
metadata:name: my-order-app-servicenamespace: my-applabels:app: my-order-app
spec:ports:- name: my-order-httpport: 8080protocol: TCPtargetPort: 8080selector:app: my-order-apptype: ClusterIP

COPY

现在我们要把Target改成8081,也就是我们的Sidecar HTTP服务器端口。


apiVersion: v1
kind: Service
metadata:name: my-order-app-servicenamespace: my-applabels:app: my-order-app
spec:ports:- name: my-order-httpport: 8080protocol: TCPtargetPort: 8081selector:app: my-order-apptype: ClusterIP

COPY

这样我们的Sidecar就搞定了。

总结

通过使用Sidecar模式,我们能够实现对微服务架构的强化,也就是关注点分离,让你专注于开车,开好车,开快车。
它提供了一种有效的方式去分摊微服务的辅助功能(如日志记录、监控、配置管理、网络通信等),而无需改动微服务的核心业务逻辑。这带来了显著的优点,包括简化开发复杂度、增强服务的可维护性和可伸缩性,以及提供了横切关注点(cross-cutting concerns)的统一管理。

优点

关注点分离:通过将非核心功能从应用程序逻辑中分离出来,开发者可以更专注于业务逻辑。
可插拔性:Sidecar可以独立于应用程序部署和更新,使得维护工作更加灵活。
一致性:在多个服务中应用相同的配置和策略,不需要在每个服务上单独配置。
扩展性:新增功能时,可以在不影响现有服务的情况下,在Sidecar中添加新的组件。
增强的能力:例如,集中日志处理、安全性控制、以及动态路由等。

缺点(Sidecar的通病):

资源使用:每个Sidecar都会消耗额外的计算和内存资源,这可能导致资源的浪费。
复杂性:虽然单个服务的复杂性降低了,但整体架构可能会因为增加的组件而变得复杂。
调试困难:由于Sidecar模式涉及多个容器协同工作,调试和追踪问题可能比传统单体应用更加困难。
网络延迟:每个请求都要通过Sidecar代理,可能会增加网络延迟。

参考

微服务侧车模式深度解析:赋能云原生应用的终极指南(自己搞一个简单SideCar?) – 小厂程序员

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

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

相关文章

快团团团长如何设置起购金额?新手教程免费学!

一、功能说明 部分团长有最低起送价的需求,这时可以通过设置起购金额来规定团员的最低起购价。 二、具体操作步骤 (一)如何设置起购金额? 在团购设置中,点击“更多团购设置”,在“其他设置”中找到“起购…

vue3使用jsQR解析二维码

1.了解jsQR jsQR是一个纯javascript脚本实现的二维码识别库&#xff0c;不仅可以在浏览器端使用&#xff0c;而且支持后端node.js环境。jsQR使用较为简单&#xff0c;有着不错的识别率。 2.效果图 3.二维码 4.下载jsqr包 npm i -d jsqr5.代码 <script setup> import …

每日一题(leetcode209):长度最小的子数组--滑动窗口

由于是区间问题&#xff0c;考虑到使用滑动窗口。 下面是我刚开始写的代码&#xff0c;虽然能通过&#xff0c;但是思维紊乱&#xff0c;循环条件应该去盯着满足情况下的条件&#xff0c;然后每次都去比较最小值&#xff0c;这样比较简洁。 class Solution { public:int minS…

卷积神经网络结构组成与解释

卷积神经网络结构组成与解释 卷积神经网络是以卷积层为主的深度网路结构&#xff0c;网络结构包括有卷积层、激活层、BN层、池化层、FC层、损失层等。卷积操作是对图像和滤波矩阵做内积&#xff08;元素相乘再求和&#xff09;的操作。 1. 卷积层 常见的卷积操作如下&#x…

比特币减半后 牛市爆发

作者&#xff1a;Arthur Hayes of Co-Founder of 100x 编译&#xff1a;Qin jin of ccvalue (以下内容仅代表作者个人观点&#xff0c;不应作为投资决策依据&#xff0c;也不应被视为参与投资交易的建议或意见&#xff09;。 Ping PingPing&#xff0c;我的手机发出的声音&…

Servlet(一)

文章目录 1.Servlet整体框架2.Servlet快速入门1.创建项目配置基本环境2.添加jar包1.在WEB-INF下创建目录lib&#xff0c;添加文件2.添加到项目中3.配置代码提示 3.src下创建文件4.实现Servlet接口5.在web.xml配置HelloServlet6.通过浏览器访问HelloServlet 3.浏览器访问Servlet…

系统架构最佳实践 -- 供应链系统架构

供应链系统是现代企业管理中不可或缺的一部分&#xff0c;它涉及到从原材料采购到产品销售的整个生产流程。一个高效的供应链系统可以帮助企业实现成本控制、库存优化和客户满意度提升等目标。在本文中&#xff0c;我们将讨论供应链系统的设计与实践。 一、供应链系统设计 业务…

前端开发攻略---Vue通过自定义指令实现元素平滑上升的动画效果(可以自定义动画时间、动画效果、动画速度等等)。

1、演示 2、介绍 这个指令不是原生自带的&#xff0c;需要手动去书写&#xff0c;但是这辈子只需要编写这一次就好了&#xff0c;后边可以反复利用。 3、关键API IntersectionObserver IntersectionObserver 是一个用于监测元素是否进入或离开视口&#xff08;viewport&#x…

系统架构最佳实践 -- 卡券系统架构设计

目录 1.卡券类型的设计&#xff1a; 2.用户领取和使用流程&#xff1a; 3.卡券发放与管理&#xff1a; 4.卡券核销与统计&#xff1a; 5.安全性和防欺诈&#xff1a; 随着电子商务的迅速发展&#xff0c;卡券系统成为了各种商家吸引用户和促销的重要手段。在设计和实现卡券…

R语言复现:轨迹增长模型发表二区文章 | 潜变量模型系列(2)

培训通知 Nhanes数据库数据挖掘&#xff0c;快速发表发文的利器&#xff0c;你来试试吧&#xff01;欢迎报名郑老师团队统计课程&#xff0c;4.20直播。 案例分享 2022年9月&#xff0c;中国四川大学学者在《Journal of Psychosomatic Research》&#xff08;二区&#xff0c;I…

2. Spring的创建和Bean的存取

经过前面的学习我们已经大体明白了 IOC 思想以及它的实现方式 DI &#xff0c;本节要讲的是如何Spring框架实现实现DI。 本节目标&#xff1a; Spring(Core) 项目创建将对象存储到 Spring 中将对象(bean)从 Spring 中取出 1. 创建 Spring 项目 与开篇演示的 Spring Boot 项目不…

斯坦福DeepMindGoogle提出SAFE:大模型长篇事实检验新标杆

关注公众号【AI论文解读】回复或者发送&#xff1a;论文解读 获取本文论文PDF 引言&#xff1a;大型语言模型的长篇事实性挑战 在当今信息爆炸的时代&#xff0c;大型语言模型&#xff08;LLMs&#xff09;在处理开放式话题的事实性问题时&#xff0c;常常会产生包含事实错…

《QT实用小工具·二十三》 Ntp校时类

1、概述 源码放在文章末尾 该项目实现了 Ntp校时类 &#xff0c;包含如下功能&#xff1a; 可设置Ntp服务器IP地址。 推荐用默认的阿里云时间服务器 ntp1.aliyun.com 收到时间信号发出。 时间精确到秒。 下面是demo演示&#xff1a; 项目部分代码如下&#xff1a; #if…

嵌入式第三天:(C语言入门)

目录 一、跳转关键字 break&#xff1a; continue&#xff1a; goto&#xff1a; 二、函数 概述&#xff1a; 函数的使用&#xff1a; 无参无返回值&#xff1a; 有参无返回值&#xff1a; 有参有返回值&#xff1a; 返回值注意点&#xff1a; 函数的声明&#xff…

攻防世界-fileinclude

题目信息 分析过程 题目说flag在flag.php中&#xff0c;通过ctrluc查看源码&#xff0c;考虑文件上传漏洞。源码如下图所示&#xff1a; 源码如下&#xff1a; <html> <head><meta http-equiv"Content-Type" content"text/html; charsetutf-8&…

字节对编码 (BPE):提升语言处理的效率和有效性

原文地址&#xff1a;byte-pair-encoding-bpe-bridging-efficiency-and-effectiveness-in-language-processing 2024 年 4 月 12 日 介绍 在快速发展的自然语言处理 (NLP) 领域&#xff0c;对人类语言高效解析和理解的追求带来了重大创新。字节对编码&#xff08;BPE&#x…

Redis中的集群(九)

集群 消息 集群中的各个节点通过发送和接收消息(message)来进行通信&#xff0c;我们称发送消息的节点为发送者(sender),接收消息 的节点成为接收者&#xff0c;如图所示。节点发送的消息主要有以下五种: 1.MEET消息:当发送者接到客户端发送的CLUSTER MEET命令时&#xff0c…

STM32-模数转化器

ADC(Analog-to-Digital Converter) 指模数转换器。是指将连续变化的模拟信号转换 为离散的数字信号的器件。 ADC相关参数说明&#xff1a; 分辨率&#xff1a; 分辨率以二进制&#xff08;或十进制&#xff09;数的位数来表示&#xff0c;一般有 8 位、10 位、12 位、16 位…

C++11 设计模式0. 设计模式的基本概念,设计模式的准则,如何学习设计模式,24种设计模式的分为3大类

一 设计模式的基本概念&#xff1a; 模式&#xff1a;指事物的标准样式 或者 理解成 针对特定问题的可重用解决方案。 设计模式&#xff0c;是在特定问题发生时的可重用解决方案。 设计模式一般用于大型项目中。 大型项目中&#xff0c;设计模式保证所设计的模块之间代码的灵…

【蓝桥杯】2024年第15届真题题目

试题 A: 握手问题 本题总分&#xff1a; 5 分 【问题描述】 小蓝组织了一场算法交流会议&#xff0c;总共有 50 人参加了本次会议。在会议上&#xff0c; 大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进 行一次握手&#xff08;且仅有一次&a…