「OpenYurt 深度解析」边缘网关缓存能力的优雅实现

「OpenYurt 深度解析」边缘网关缓存能力的优雅实现

OpenYurt:延伸原生 K8s 的能力到边缘

阿里云边缘容器服务上线 1 年后,正式开源了云原生边缘计算解决方案 OpenYurt,跟其他开源的容器化边缘计算方案不同的地方在于:OpenYurt里云优惠 秉持 Extendin里云双十一红包g your native Kubernetes里云服务器活动 to edge 的理念,对 Kubernetes 系统零修改,并提供一键式转换原生 Kubernetes 为 OpenYurt,让原生 K8s 集群具备边缘集群能力。

同时随着 OpenYurt 的持续演进,阿里云优惠服务器也一定会继续保持如下发展理念:

  • 非侵入式增强 K8s
  • 保持和云原生社区主流技术同步演进

OpenYurt 如何解决边缘自治问题

想要实阿里云200元代金券现将 Kuber阿里云拼团活动netes 系统延展到边缘计算场景,那么边缘节点将通过公网和云端连接双11活动阿里云的作用,网络连接有很大不可控因素,可能带来边缘业务运行的不稳定因素,这是云原生和边缘计算融合的主要难点之一。

解决这个问题,需要使边缘侧具有自治能力,即当云边网络断开或者连接不稳定时,确保边缘业务可以持续运行。在 OpenYurt 中,该能力由 yurt-controller-manager 和 YurtHub阿里云和双十一有什么关系 组件提供。

1. YurtHub 架构

在之前的文章阿里云中,我们详细介绍了 YurtHub 组件的能力。阿里云代金券阿里云优惠其架构图如下:

「OpenYurt 深度解析」边缘网关缓存能力的优雅实现

YurtHub 是一个带有数据缓存功能的“透明网关”,和云端网络断连状态下,如果节点或者组件重启,各个组件(kubelet/kube-proxy 等)将从 YurtHub 中获取到业务容器相关数据,有效解决边缘自治的问题。这也意味着我们需要实现一个轻量的带数据缓存能力的反向代理。阿里云服务器拼团活动

2. 第一想法

实现一个缓存数据的反向代阿里云双十一理,第一想法就是从 response.Body 中读取数据,然后分别返回给请求 client阿里双11数据 和本地的 Cach双11活动阿里云的作用e 模块。伪代码如下:

func HandleResponse(rw http.Respon阿里云双11优惠seWriter, resp *http.Response)阿里云双11优惠 {
bodyBytes, _ := ioutil.ReadAll(resp.阿里云双十一2019Body)
go func() {
// cache response on local阿里双11数据 disk
cacher.Write(bodyBytes)
}
// client reads data from response
rw.Write(bodyBytes)
}

当深入思考后,在 Kubernetes 系统中,上述实现会引发下面的问题:

  • 阿里云代金券如何使用题 1:流式数据需要如何处理(如: K8s 中的 wat阿里云服务器双十一特惠ch 请求),意味 ioutil.ReadAll() 一次调用无法返回所有数据。即如何可以返回流数据同时又缓存流数据。
  • 阿里云活动题 2:同时在本地缓存数据前,阿里云双十一活动地址有可能需要对传入的 byte slice 数据先进行清洗处理。这意味着需要修改 byte sl阿里云双11ice,或者先备份 byte slice 再处阿里云理。这样会造成内存的大量消耗,同时针对流式数据,到底申请多大的 slice 也不好处理。

3. 优雅实阿里巴巴双十一市场活动现探讨

针对上面的问题,我们将问题逐阿里巴巴双十一市场活动个抽象,可以发现更优雅的实现方法。

  • 问题 1:如何对流数据同时进行读写

针对流式数据的读写(一边返回一边缓存),如下图所示,其实需要的不过是把 response.Body(io.Reader) 转换成一个 io.Re阿里云双十一活动拼团ader 和一个 io.Writer。或者说是一个 io.Reader 和 io.Writer 合成一个 i阿里云双十一o.Reader。这很容易就联想到 Linux 里面的 Tee 命令。

「OpenYurt 深度解析」边缘网关缓存能力的优雅实现

而在 Golang 中 Tee 命令是实现就是io.阿里云代金券如何使用TeeReader,那问题 1 的伪代码如下:

func Handle阿里双11数据Response(rw http.ResponseWriter, resp *http.Response) {
// create TeeReader with response.Body and cache阿里云几折优惠r
newRespBody := io.阿里云双十一红包TeeReader(resp.Body, cacher)
// client reads data from response
io.Copy(rw, newRespBody)
}

通过 Tee阿里云代金券如何使用Reader 的对 Response.Body 和 Cacher阿里云双十一2020 的整合,当请求 clie阿里云优惠券nt 端从 response.Body 中读取数据时,将同时向 Cache 中写入返回数据,优雅的解决了流阿里云过了优惠期多少钱式数据的处理。

  • 问题 2:如何在缓存前先清今年双十一京东与阿里洗流数据

如下图所示,缓阿里双11现在交易额存前先清洗阿里云服务器双11活动流数据,请求端和过滤端需要同时读取 response.Body(2 次读阿里云双十一活动取问题)。也就是需要将 res阿里云代金券可以赠送吗ponse.Body(io.Reader) 转换成两个 io.Reader。

「OpenYurt 深度解析」边缘网关缓存能力的优雅实现

也意味着问题 2 转双11活动阿里云的作用化成阿里云双十一活动:问题 1 中缓存端的 io.Writer 转换成 Data F阿里云双十一优惠ilter 的 io.Reader。其实在 Li推广阿里云双十一赚10万nux 命令中也能找到类似命令,就是管道。因此问题 2 的伪代码如下:

fun阿里云双十一c HandleResponse(rw http.ResponseWriter, resp *http.Response) {
pr, pw := io.Pipe()
// create TeeReader with re阿里云双十一活动sponse.Body and Pipe writer
newRespBody :=阿里会员日和双十一 io.TeeReader(resp.Body, pw)
go func() {
/推广阿里云双十一赚10万/ filter reads data from resp阿里云双十一优惠活动onse
io阿里云双十一.Copy(dataFilter, pr)
}
// client reads data from response
io.Copy(rw, newRespBody)
}

通过 io.TeeReader 和 io.P阿里双11现在交易额iPe,当请阿里云服务器双11活动求 client 端从 response.Body 中读取数据时,Filt阿里云双十一er 将同时从 Response 读取到数据,优雅的解决了流式数据的 2 次读阿里云双十一取问题。

YurtHub 实现

最后看一阿里云服务器双十一特惠下 YurtHub 中相关实现,由于 Response.Body阿里巴巴双十一有优惠吗 为 io.ReadCloser,所以实现了 dualReadCloser。同时 YurtHub 可能也面临对 http.Request 的缓存,所以增加了 isRespBody 参数用于判定是否需要负责关闭 response.Body。

// https:/双11活动阿里云的作用/github.com/openyurtio/openyurt/blob/master/pkg/yurthub/util/util.go#L15阿里云双十一6
// NewDualReadCloser create an dualReadCloser object
func NewDualReadCloser(rc io.Rea阿里云双十一2020dCloser, isRespB阿里云双十一活动拼团ody bool) (io.ReadClose阿里云双十一2020r, io.ReadCloser) {
pr, pw := io.Pipe()
dr := &d阿里云代金券可以赠送吗ualReadClos阿里云双十一er{
rc:         rc,
pw:         pw,
isRespBody: isRespBody,
}
return d阿里云双11活动r, pr
}
type dualReadCloser struct {
rc io.ReadCloser阿里云优惠券
pw *io.PipeWriter
// isRespBody shows rc(is.ReadCloser) is a response.Body
// or not(maybe a request.Body). if it is true(it's a response.Body),
// we should close the response body in Close fun阿里云双十一活动拼团c, else not,
// it(reque阿里云双十一活动2018st b阿里云ody) will be closed by http request caller
isRespBody bool
}
// Read read data into p a阿里云双十一活动拼团nd wr阿里云双十一活动拼团ite into pipe
func (dr *du阿里云双十一活动拼团alReadCloser) Read(p []byte) (n int, err er阿里云双十一活动ror) {
n, err = dr.rc.Read(p)
if n > 0 {
if n, err := dr阿里云双十一2019.pw.Write(p[:n]); err != nil {
klog.Errorf("dualRea阿里云双十一活动拼团der: failed to write %v", err)
return n, err
}
}
return
}
// Clos阿里云优惠券最新领取e close two readers
func (dr *阿里云双十一活动dualReadCloser) Close() error {
errs := ma阿里云双十一活动2018ke([]error, 0)
if dr.isRespBody {
if err := dr.rc.Close(); err != nil {
errs = app阿里云服务器拼团活动end(errs阿里云双十一活动攻略, err)
}
}
if err := dr.pw.Close(); err != nil {
errs = append(errs, err)
}
if len(errs) != 0 {
retu阿里云和双十一有什么关系rn fmt.Errorf("failed to close dualReader, %v", errs)
}
return nil
}

在使用 dualReadCloser 时阿里云双十一,可以阿里云双十一活动地址
httputil.NewSingleHostReverseProxy的modifyResponse()方法中看到。代码如下:

// https://github.com/openyurtio/openyurt/blob云服务器双11活动/master/pkg/yurthub/proxy/remote/remote.g阿里云优惠券领取o#L85
func (rp *RemoteProxy) modifyResponse(resp *http.Response) erro阿里云双11活动r {rambohe-ch, 10 mon阿里巴巴拼团怎么拼ths ago: • hello openyurt
//2019双11阿里销售额是多少 省略部分前置检查
rc,阿里云双十一2020 pr推广阿里云双十一赚10万c := util.NewDualReadCloser(resp.Body, true)
g阿里云双11优惠o func(ctx co阿里云双十一ntext.Context, prc io.ReadCloser, stopCh <-chan struct{}) {
err := rp.cacheMgr.CacheResponse(ctx, prc, stopCh)
if err != nil && er阿里云双十一r != io.EOF &amp阿里云双十一2019;& err != context.Canceled {
klog.Errorf("%s response cache ended with error, %v", util.ReqStrin阿里云服务器双11活动g(req), err)
}
}(ctx, prc, rp.stopCh)
resp.Body = rc
}

总结

OpenYu阿里云双十一活动rt 于 2020 年 9 月进入 CNCF 沙箱后,持续保持了快速发展和迭代,在社区同学一起努力下,目前已经开源的能力有:

  • 边缘自治
  • 边缘单元化管理
  • 云边协同运维
  • 一键式无缝转换能力

作者 | 何淋波(新胜)

原文链接