跟随,学习,进步

详解 Kubernetes 垃圾收集器的实现原理

2019-02-17 19:44:00 Draveness

垃圾收集器在 Kubernetes 中的作用就是删除之前有所有者但是现在所有者已经不存在的对象,例如删除 ReplicaSet 时会删除它依赖的 Pod,虽然它的名字是垃圾收集器,但是它在 Kubernetes 中还是以控制器的形式进行设计和实现的。


详解 Kubernetes ReplicaSet 的实现原理

2019-02-16 23:14:00 Draveness

Kubernetes 中的 ReplicaSet 主要的作用是维持一组 Pod 副本的运行,它的主要作用就是保证一定数量的 Pod 能够在集群中正常运行,它会持续监听这些 Pod 的运行状态,在 Pod 发生故障重启数量减少时重新运行新的 Pod 副本。


通过自定义Istio Mixer Adapter在JWT场景下实现用户封禁

2019-02-15 17:09:24 Yisaer

介绍互联网服务离不开用户认证。JSON Web Token(后简称JWT)是一个轻巧,分布式的用户授权鉴权规范。和过去的session数据持久化的方案相比,JWT有着分布式鉴权的特点,避免了session用户认证时单点失败引起所有服务都无法正常使用的窘境,从而在微服务架构设计下越来越受欢迎。然而JWT单点授权,分布鉴权的特点也给我们带来了一个问题,即服务端无法主动回收或者BAN出相应的Token,使得即使某个服务主动封禁了一个用户时,这个用户同样可以使用之前的JWT来从其他服务获取资源。本文我们将阐述利用Istio Mixer Adapter的能力,来将所有请求在服务网格的入口边缘层进行JWT检查的例子,从而实现用户封禁与主动逐出JWT等功能。背景在我之前的投稿中,描绘了一个非常简单的基于K8S平台的业务场景,在这里我们将会基于这个场景来进行讨论。对于一个简单的微服务场景,我们有着三个服务在Istio服务网格中管理。同时集群外的请求将会通过nginx-ingress转发给istio-ingressgateway以后,通过Istio VirtualService的HTTPRoute的能力转发给对应的服务,这里不再赘述。从下图的架构模式中,我们可以看到所有的请求在进入网格时,都会通过istio-ingressgateway这个边缘节点,从而涌现出了一个非常显而易见的想法,即如果我们在所有的请求进入服务网格边缘时,进行特定的检查与策略,那么我们就能将某些不符合某种规则的请求拒绝的网格之外,比如那些携带被主动封禁JWT的HTTP请求。了解Istio Mixer为了达到我们上述的目的,我们首先需要了解一下Istio Mixer这个网格控制层的组件。Istio Mixer 提供了一个适配器模型,它允许我们通过为Mixer创建用于外部基础设施后端接口的处理器来开发适配器。Mixer还提供了一组模版,每个模板都为适配器提供了不同的元数据集。在我们的场景下,我们将使用Auhtorization模板来获取我们每个请求中的元数据,然后通过Mixer check的模式来将在HTTP请求通过istio-ingressgateway进入服务网格前,通过Mixer Adapter来进行检查。在Istio Mixer的描述中,我们可以发现每个请求在到达数据层时,都会向Mixer做一次check操作,而当请求结束后则会向Mixer做一次report操作。在我们的场景中,我们将会在请求到达istio-ingressgateway时检查这个请求中的JWT鉴权,通过JWT的Payload中的信息来决定是否要将请求放行进入网格内部。得益于Mixer强大的扩展能力,我们将通过经典的Handler-Instances-Rule适配模型来一步步展开,同时也意味着我们将要编写一个自定义的Istio Mixer Adapter。Mixer适配模型那么怎么通俗易懂的理解Handler-Instances-Rule这三者的关系呢?在我的理解下,当每个请求在服务网格的数据层中游走时,都会在开始与结束时带上各种元信息向Mixer组件通信。而Mixer组件则会根据Rule来将特定的请求中的特定的数据交给特定的处理器去检查或者是记录。那么对于特定的请求,则是通过Rule去决定;对于特定的数据,则是通过Instances去决定;对于特定的处理器,则是通过Handler去决定。最终Rule还把自己与Instances和Handler绑定在一起,从而让Mixer理解了将哪些请求用哪些数据做哪些处理。在这里我们可以通过Istio Policies Task中的黑白名单机制来理解一下这个模型。在这里appversion.listentry作为instances,通过将list entry作为模版,获取了每个请求中的source.labels[“version”]的值,即特定的数据。whitelist.listchecker作为handler,则是告诉了背后的处理器作为白名单模式只通过数据是v1与v2的请求,即特定的处理器。最后checkversion.rule作为rule,将appversion.listentry和whitelist.listchecker两者绑定在一起,并通过match字段指明哪些请求会经过这些处理流程,即特定的请求。123456789101112131415161718192021222324252627282930## instancesapiVersion: config.istio.io/v1alpha2kind: listentrymetadata: name: appversionspec: value: source.labels["version"]---## handlerapiVersion: config.istio.io/v1alpha2kind: listcheckermetadata: name: whitelistspec: # providerUrl: ordinarily black and white lists are maintained # externally and fetched asynchronously using the providerUrl. overrides: ["v1", "v2"] # overrides provide a static list blacklist: false---## ruleapiVersion: config.istio.io/v1alpha2kind: rulemetadata: name: checkversionspec: match: destination.labels["app"] == "ratings" actions: - handler: whitelist.listchecker instances: - appversion.listentryJWT Check 的架构设计当我们理解了以上的Mixer扩展模型以后,那么对于我们在文章开头中的JWT封禁需求的Handler-Instances-Rule的模型就非常显而易见了。在我们的场景下,我们需要将所有带有JWT并且从istio-ingressgateway准备进入网格边缘的请求作为我们特定的请求,然后从每个请求中,我们都要获取request.Header[“Authorization”]这个值来作为我们特定的数据,最后我们通过特定的处理器来解析这个数据,并在处理器中通过自定义的策略来决定这个请求是否通过。当我们搞清楚了这么一个模型以后,那么之后的问题就一下子迎刃而解了。在我们的设计中,我们将要自定义一个JWTAdapter服务来作为特定的处理器,JWTAdapter将会通过HTTP通信把数据转交给Adapter-Service来让Adapter-Service来判断这个请求是否合法,而Adapter-Service的凭证则是通过与业务服务的通信所决定。在我们的场景中,假设每个请求所携带的JWT的Payload中有一个email属性来作为用户的唯一标识,当业务领域中的账户服务决定封禁某个用户时,他将会通知Adapter-Service,后者将会把这个信息存于某个数据持久服务中,比如Redis服务。当JWT-Adapter服务向Adapter-Service服务询问这个请求是否合法时,Adapter-Service将会通过Payload中Email属性在Redis中查询,如果查询到对应的数据,则代表这个用户被封禁,即这个请求不予通过,反之亦然。如何自定义编写一个Adapter?说实话,自定义编写Adapter是一个上手门槛较为陡峭的一件事情。我在这里因为篇幅原因不能完全一步步细说自定义Adapter的步骤。在这里我推荐对自定义编写Adapter有兴趣的人可以根据官网的自定义Mixer Adapter开发指南和自定义Mixer Adapter详细步骤来进行学习和尝试。在这里我给出在我的JWT-Adapter中的关键函数来进行描述。123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354func (s *JwtAdapter) HandleAuthorization(ctx context.Context, r *authorization.HandleAuthorizationRequest) (*v1beta1.CheckResult, error) { log.Infof("received request %v\n", *r) props := decodeValueMap(r.Instance.Subject.Properties)var Authorization interface{}if len(props["custom_token_auth"].(string)) 0 {Authorization = props["custom_token_auth"]} else { // 没有获取到JWT,直接将请求放行return &v1beta1.CheckResult{Status: status.OK,}, nil}cookie := props["custom_request_cookie"]host := props["custom_request_host"]if host == "www.example.com" {url := userService + "/check"request, err := http.NewRequest("GET", url, nil)if err != nil { //出现异常时,直接将请求放行return &v1beta1.CheckResult{Status: status.OK,}, nil}request.Header.Add("Content-Type", "application/json; charset=utf-8")request.Header.Add("cookie", cookie.(string)) request.Header.Add("Authorization", Authorization.(string)) // 发送请求给Adapter-Serviceresponse, _ := client.Do(request)if response != nil && response.StatusCode == http.StatusOK {body, err := ioutil.ReadAll(response.Body)if err != nil { //如果有异常 log.Infof(err) //记录异常即刻} else { log.Infof("success to get response from adapter-service")var value map[string]interface{}json.Unmarshal(body, &value)if value["pass"] == false {//当用户确实返回处于封禁状态中时,才返回封禁结果return &v1beta1.CheckResult{Status: status.WithPermissionDenied("Banned"),}, nil}}}}log.Infof("jwtadapter don't have enough reason to reject this request")return &v1beta1.CheckResult{Status: status.OK,}, nil}通过以上描述可以发现的是,在我们的场景下,我们当且仅当从Adapter-Service中确实得到了不允许通过的结果才将这个请求进行拒绝处理,而对其他情况一律进行了放行处理,即使发生了某些错误与异常。由于我们的错误处理会直接影响到这些请求能否在网格中通行,所在做Istio Mixer Check时需要时刻记住的到底是放行特定的请求,还是拒绝特定的请求,在这一点处理上需要十分谨慎与小心。Handler-Instances-Rule当我们将自己的Adapter上线以后,我们只要通过声明我们得的Mixer扩展模型让Mixer识别这个Adapter并且正确处理我们想要的请求即可。这里我们再回顾一下我们之前所提到的特定的请求,特定的数据,特定的处理器。对于特定的请求,我们需要将网格边缘的请求筛选出来,所以我们可以通过host是www.example.com并且携带了JWT作为条件将请求筛选出来。对于特定的数据,我们选用authorization作为模版,取出header中的JWT数据,最后通过特定的处理器,将这个check请求交给jwt-adapter。至此,我们通过Istio Mixer Aadapter来进行JWT封禁的需求场景算是基本完成了。12345678910111213141516171819202122232425262728293031323334353637# handler adapterapiVersion: "config.istio.io/v1alpha2"kind: handlermetadata: name: h1 namespace: istio-systemspec: adapter: jwtadapter connection: address: "[::]:44225"---## instancesapiVersion: "config.istio.io/v1alpha2"kind: instancemetadata: name: icheck namespace: istio-systemspec: template: authorization params: subject: properties: custom_token_auth: request.headers["Authorization"]---# rule to dispatch to handler h1apiVersion: "config.istio.io/v1alpha2"kind: rulemetadata: name: r1 namespace: istio-systemspec: match: ( match(request.headers["Authorization"],"Bearer*") == true ) && ( match(request.host,"*.com") == true ) actions: - handler: h1.istio-system instances: - icheck---扩展阅读网格边缘层验证JWT的可行性?既然在网格边缘层能对JWT进行检查,那么能否可以做成在网格边缘层同时也进行JWT的验证?答: 在我最初做Mixer Check时确实想到过这件事情,并且无独有偶,在PlanGrid在Istio中的用户鉴权实践这篇文章中,PlanGrid通过EnvoyFilter实现了在网格边缘层进行JWT以及其他鉴权协议的鉴权。但对此我的看法是,对于JWT鉴权的场景,我并不推荐这么做。因为微服务场景中,我们使用JWT的初衷就是为了分布式鉴权来分散某个服务的单点故障所带来的鉴权层的风险。当我们将用户鉴权再一次集中在网格边缘时,我们等于再一次将风险集中在了网格边缘这个单点。一旦istio-ingressgateway挂了,那么背后所有暴露的API服务将毫无防备,所以鉴权必须放在每个微服务内。另一方面,在我的《深入浅出istio》读后感中提到,对于生产环境使用Istio,必须拥有一套备用的不使用Istio的环境方案,这意味着当Istio出现故障时,可以立即通过切换不使用Istio的备用环境来继续提供服务。这同时意味着Istio所提供的能力与服务不应该与业务服务所强绑定在一起,这也是为什么我在上文中将Jwt-Adapter与后面的Adapter-Service成为插件服务的原因。JWT封禁用户这个能力对我们就像一个插件一样,即装即用。即使当我们切换为备用环境时无法使用Istio,暂时失去用户封禁这个能力在我们的产品层面也完全可以接受,但对于用户鉴权则不可能。所以这意味着当我们使用Istio的能力时,一定要时刻想清楚当我们失去Istio时我们该如何应对。关于作者从去年毕业以后一直对服务网格与CloudNative领域充满兴趣,在工作中使用Istio在生产环境中也将近有了半年多的时间,写作分享则是平时的业余爱好之一。如果你对服务网格或者是CloudNative领域有兴趣,或者是对我的技术文章写作有想法与建议的话,欢迎联系我交流。Github 博客RSS订阅


每周分享第 43 期

2019-02-15 03:51:20 阮一峰

这里记录过去一周,我看到的值得分享的东西,每周五发布。...


京东PLUS会员项目前端性能优化实践

2019-02-15 01:46:32 甄玉磊

作者:Frans 京东PLUS会员项目是国内第一个电商付费会员项目,正式开通的会员数量已破千万。我团队从2016年接手这个项目的前端开发工作,一路见证了它的高速成长,也为此贡献了自己的力量。 这个项目有几个特点: 第一,需求多。移动端使用 H5 开发,曾有人问为什么不用原生或者 RN 开发? 我觉得吧,以这个项目的需求数量和迭代速度来看,连 H5 都难以 hold 的住,还是不要奢望原生和 RN 了。 第二,产品经理多。一般的项目对接一两个产品经理,这个项目我们需要对接一个异地的产品经理“团队”;一般的项目换产品经理一个一个的换,这个项目一批一批的换……我们已经送走好几届PLUS会员产品经理了。铁打的研发,流水的产品经理。 所以说,PLUS会员项目是业务方滴,也是项目经理滴,还是产品经理滴,但终归是俺们研发滴。每念及此,我的耳边总会响起叶倩文的那首老歌:“天地悠悠,过客匆匆,潮起又潮落…”。 书归正传。用户众多和需求迭代频繁,确保线上安全稳定始终是第一要务。所以在架构调整和性能优化方面我们一直都小心翼翼,以一些小修小补为主,只有到大规模改版的时候才会有大的升级改造。不过,平时我们对这些问题的思考和实践却不曾停止过,我们验证了一些行之有效的优化方案,在下一波改版中将会得到应用。 我虽然不完全认同“前端开发每十八个月难度翻一倍”的说法,但这一行发展迭代速度快却是不争的事实。若等到这些优化方案全都应用上再出来念叨,可能就显得不那么新鲜了。所以,我决定先把这些方案拿出来分享,和感兴趣的小伙伴一起讨论,进一步完善。 这些方案主要针对移动端,优化核心方向是提高首页的加载速度,特别是首屏和弱网络环境下的加载速度。从持久化缓存、削减代码量、优化接口请求、提升主观感受等方面下手,比较大的改动是应用 PWA 和升级架构。 PWA 离线缓存可以极大的提升用户体验,不过它对于首次加载速度并无提升作用,还得靠其他优化手段,这是一套组合拳。我们先从架构升级说起吧。 架构升级 项目计划迁移到 Gaea4.0 脚手架[1],这是我们团队基于 webpack 4 开发的一套通用 Vue 单页面应用脚手架,此前的系列版本已经过数十个项目的验证,还是比较稳定的。近期新推出4.0版相较之前版本有着不小的改进。 webpack 升级到了 4.0 Babel 升级到了 7.0 Vue-loader 升级到了 15 重构了上传插件,一键上传到测试服务器更快更稳定 针对我厂手机和电脑位于不同局域网无法互访的问题,集成了自主研发的 Carefree 解决方案[2],方便真机测试调试 集成了 NutUI 组件库[3],可按需加载需要的UI组件 集成了自主研发的基于swagger的数据mock工具SMOCK[4] 支持自动生成骨架屏[5] 支持 PWA … 迁移有几个主要目的: […]

tags: 前端开发


记录一次mysql升级之后rails遇到的问题

2019-02-14 11:14:12 邹超

mysql升级之后数据文件夹共用, 但是无法使用db:migrate 错误信息大致如下: E, [2019-02-14T11:06:23.650106 #68912] ERROR -- : Mysql2::Error: Table 'performance_schema.session_variables' doesn't exist: SHOW VARIABLES LIKE 'character_set_database' rake aborted! ActiveRecord::StatementInvalid: Mysql2::Error: Table 'performance_schema.session_variables' doesn't exist: SHOW VARIABLES LIKE 'character_set_database' 解决方式: mysql_upgrade -u 用户名 -p --force 然后一定记得重启mysql服务


CNCF年度报告解读(2018年)

2019-02-13 17:23:01 Jimmy Song

2019年2月初,CNCF 发布了2018年的年度报告,这是 CNCF 继2017年度报告之后,第二次发布年度报告,2017年度的报告只有区区14页,今


Elixir 从入门到放弃

2019-02-13 08:00:00 Draveness

过去将近一年的时间里,作者在日常工作中需要经常与 Elixir 这门编程语言打交道,包括使用 Phoenix 框架开发一些后端服务、实现定制的组件,读过之前 2018 年总结 一文的读者相信对此也有所了解。


npx 使用教程

2019-02-09 20:12:07 阮一峰

npm 从5.2版开始,增加了 npx 命令。它有很多用处,本文介绍该命令的主要使用场景。...


指令集架构、机器码与 Go 语言

2019-02-08 08:00:00 Draveness

Go 语言编译的最后一个阶段就是根据 SSA 中间代码生成机器码了,这里谈的机器码生成就是在目标 CPU 架构上能够运行的代码,中间代码生成 一节简单介绍的从抽象语法树到 SSA 中间代码的处理过程,处理 SSA 的将近 50 个步骤中有一些过程严格上来说其实是属于机器码生成阶段的。


找回密码的功能设计

2019-02-07 15:14:02 阮一峰

所有需要登录的网站,都会提供"找回密码"的功能,防止用户忘记密码。...


详解 Golang 中间代码生成

2019-02-04 08:00:00 Draveness

前两节介绍的 词法与语法分析 以及 类型检查 两个部分都属于编译器前端,它们负责对源代码进行分析并检查其中存在的词法和语法错误,经过这两个阶段生成的抽象语法树已经不存在任何的结构上的错误了,从这一节开始就进入了编译器后端的工作 — 中间代码生成 和 机器码生成 了,这里会介绍 Go 语言编译的中间代码生成阶段。


Golang 如何进行类型检查

2019-02-03 08:00:00 Draveness

我们在上一节中介绍了 Golang 的第一个编译阶段 — 通过 词法和语法分析器 的解析得到了抽象语法树,在这里就会继续介绍编译器执行的下一个过程 — 类型检查。


解析器眼中的 Go 语言

2019-02-02 08:00:00 Draveness

代码其实就是按照约定格式编写的一堆字符串,工程师可以在脑内对语言的源代码进行编译并运行目标程序,这是因为经过训练的软件工程师能够对本来无意义的字符串进行分组和分析,按照约定的语法来理解源代码。既然工程师能够按照一定的方式理解和编译 Go 语言的源代码,那么我们如何模拟人理解源代码的方式构建一个能够分析编程语言代码的程序呢。


《深入浅出Istio》读后感

2019-02-01 11:17:00 Yisaer

前言《深入浅出Istio》这本书这两天开始卖了,我也第一时间入手了以后到现在已经基本上全部翻完了。在这里记录一下看完这本书的读后感。总体来说,这本书是一本既适合Istio本身有一定了解程度的使用者,也适合对ServiceMesh初学者的去学习Istio的书籍。这本书比较全面的介绍并总结了Istio的各个组件及其使用方法,并给出了许多具体的场景。作为一名接触ServiceMesh领域和Istio快小半年的我来说,对于书中一些比较基础的章节和内容快速翻了一翻,同时也对部分对我帮助非常大的章节做了一些总结和心得。在这里用一篇读后感记录我读完以后的感受。关于书籍作者作者在ServiceMesher社区里面是一个非常活跃的人,对istio.io的中文化工作做了非常大的贡献。作为一个大部分时间在社区内处于一个围观群众,在这里对作者对国内ServiceMesh领域做出的贡献表示由衷的感谢。全书结构整本书分为十章,整本书我重点看了第1,2,3,5,8,10。第七章重点看了后半部分。服务网格历史服务网格的特性介绍istio安装istio详解Helm部署istioIstio插件服务Http流量管理Mixer应用Istio安全生产环境使用Istio的建议正文作者从微服务的诞生和发展谈起,简略谈了一下在微服务架构为我们解决了许多老问题时,它所给我们带来的一些新的问题。为了解决这些问题,Kubernetes为代表的容器云系统出现提供了部署、调度、伸缩等功能,,而ServiceMesh则应运而生去解决如何管理、控制、保障微服务之间的通信。随后,作者挑了几个重要的产品与事件来梳理了ServiceMesh的发展历史。从SpringCloud确定微服务治理的标准特性,到Linkerd发布后受人关注,再到Istio横空出世。ServiceMesh领域中目前发展的最好的毫无疑问是Istio。这不仅是因为Istio吸取了前面产品的经验,同样也背靠了Google,IBM和Lyft这三个公司共同组成的开发团队。由于我接触ServiceMesh领域时,Istio都已经发布到0.7版本了,所以这块的内容让我了解了整个ServiceMesh领域的发展历史。在第二章,作者着重聊了一下Istio官网首页所印着的四个特性:连接、安全、策略、观察,所分别代表的意义和场景。然后在第三章介绍了Istio整体架构和每个组件所承载的意义和功能以及一些Istio自定义的CRD。关于Istio的架构设计和功能组件Istio官网本身就有非常详细的介绍了,直接看官网介绍就行,对于部分CRD的介绍挺好的,可以帮助理解每个Istio组件对应了哪些Istio配置文件。第四章和第五章这块都是关于安装Istio的,这一块我比较熟悉就直接跳过了。同时对于个人开发者学习Istio而言,需要的是一个更快的本地搭建Istio环境的教程,这里推荐一个更简单的快速本地搭建istio教程第五章着重介绍了Istio安装文件种的Helm结构,以及每个参数所代表的意义。这一块我觉得对我的帮助非常大,由于之前我在生产环境安装istio都是通过我本地开发机helm template一个完整的安装文件,然后一并apply到生产环境上。这给我至少带来了两个大问题:我的本地开发机拥有一个具有读写权限的生产环境k8s账号修改各个部件相关参数变得十分麻烦目前在这上周我已经全部回收了我们开发组内所有人的生产环境权限,统一通过K8S DashBoard进行操作。当然,这也意味一旦需要更新istio就不能再走本地apply安装文件的方式。一个更加科学的方法则是通过CICD系统,用helm install/upgrade来管理生产环境的istio配置。所以,掌握istio的helm文件结构就显得非常重要,这块第五章给我的帮助很大。第六章作者介绍了Istio的一些官方推荐的插件服务如Prometheus,Grafana,Jaeger这些。我就直接跳了。第七第八章作者介绍了通过Istio进行网格的Http管理和Mixer应用。这两张是本书的两个大头,当然同样也是Istio应用的两个大头。对于第七章,作者介绍了VirtualService,HttpRoute,Gateway这些相关概念,以及通过这些组件进行负载,转发,灰度这些内容,基本上我就快速看了过去。我个人在istio的实践上,也已经在生产环境上通过istio进行灰度发布,所以对于这块内容我已经比较熟悉了。相关资料: coohom在生产环境上使用istio的实践与经验第七章的后半段提到了通过Istio在生产环境进行故障演练的方案,这一块挺让我耳目一新的.一方面是没想到还能这么玩,一方面是在生产环境的故障演练同样也是我今年上半年将要去做的一个目标之一,这块对于故障注入与故障演练的场景方案对我帮助很大。第八章作者着重介绍了通过Mixer来进行一些黑白名单、限流、自定义监控指标这些操作。在Istio官网上关于Mixer的大部分内容我也已经全部看完并实践过了,所以这块内容我看的比较快。一个比较遗憾的一点是没有看到关于如何自定义Adapter相关的介绍,这一块是Mixer有着非常大潜力与价值的一块内容,但同时也有着不小的门槛。这一块我前不久一直在花时间调研并通过自定义Istio Mixer Adapter完成了一个比较常见的需求,这次放假有空将会整理一下。第九章讲了Istio安全认证这块,我暂时直接跳过了,在我目前的场景中,生产环境集群内所有服务都将长期处于互相信任的状态,所以我暂且并不关心这方面内容。第十章作者给了一些在生产环境上使用Istio的建议,有大部分内容和我在生产环境上实践所的出来的结论相同,以及Istio目前的一些发展问题。关于生产环境使用Istio的建议,这里我摘录几条我深表赞同的:永远准备一套不用Istio的备用环境,( 目前我们服务的生产环境长期保留了主备服务,主服务使用Istio,备用业务则不使用Istio,每当进行istio升级或者是部分参数调整时都会提前进行主备切换,等升级调整验证完毕后才切换回来)确定使用Istio的功能范围 (在我们的场景中,只有真正的业务服务才被服务网格管理,其余不需要网格管理的服务绝对不强上网格)时刻考虑Istio功能的性价比 (不为了用功能而用功能,Istio Citadel安全功能对于我们来说目前收益接近于零,但风险极大,所以就坚决不用)同时对于Istio这个产品发展的现状,作者给出了一定的担心,即目前Istio团队,发布的产品API稳定性太不稳定,不向后兼容,很多API全部改写。另一方面在发布质量上也出现过比较大的问题,造成了版本回退,发布延期等问题。同时Istio组件目前本身也有着一些瓶颈与问题如Mixer的复杂性与高成本学习,Pilot的性能瓶颈,SideCar的性能消耗。以上这些都有待Istio团队去解决。最后整体来看,对于Istio,我个人认为Istio目前的发展状况在ServiceMesh领域中还并没有像K8S取得事实胜利,可能Istio也有可能步Linkerd的后路,为未来的产品开路和经验,但是ServiceMesh这条路无疑是正确的,我也会继续关注ServiceMesh和istio在2019年新的表现。


每周分享第 42 期

2019-02-01 10:08:23 阮一峰

这里记录过去一周,我看到的值得分享的东西,每周五发布。...


Go 语言编译过程概述

2019-02-01 08:00:00 Draveness

Golang 是一门需要编译才能运行的编程语言,也就说代码在运行之前需要通过编译器生成二进制机器码,随后二进制文件才能在目标机器上运行,如果我们想要了解 Go 语言的实现原理,理解它的编译过程就是一个没有办法绕过的事情。


2018 年总结 · 初窥门径

2019-01-31 08:00:00 Draveness

一转眼 2018 年就过去了,回想了一下今年确实做了非常多的事情,从零搭建交易所服务到负责基础架构以及微服务治理,整个 2018 年也是作者服务端技术逐渐成熟的一年,对于未来的职业规划和方向也变得越来越清晰,到了年末的时候也确实开始回忆和反思这一年个人到底有哪些提升和进步以及有哪些地方能够做得更好。


敏捷转型是根据具体问题的演进过程

2019-01-29 21:03:09 李强

敏捷转型是根据具体问题的演进过程,也是和各干系人真诚合作的结果。敏捷教练需要在战壕里。

tags: 敏捷


Kubernetes与云原生2018年终总结及2019年展望

2019-01-29 13:54:50 Jimmy Song

去年我写了Kubernetes与云原生2017年年终总结及2018年展望,按照惯例也应该推出2018年的总结和2019年的展望了,写这篇文章