前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用服务网格/Istio开发微服务1:背景及开发约定

使用服务网格/Istio开发微服务1:背景及开发约定

原创
作者头像
谢正伟
发布2020-05-25 10:07:51
1.1K0
发布2020-05-25 10:07:51
举报
文章被收录于专栏:云原生研究云原生研究

背景

微服务会把大的应用拆分成若干小的服务应用和前端应用,如何协调/治理这些应用,并解决在开发中遇到的各种问题是微服务面临的挑战。通常一个微服务系统需要关注的问题有:

  • 服务的注册发现
  • 服务间的远程调用
  • 负载均衡/东西向流量操控
  • 网关/南北向流量操控
  • 弹性伸缩
  • 服务的调用链跟踪
  • 日志收集和告警
  • 熔断和限流
  • 远程配置管理
  • 健康检测
  • 故障恢复
  • 服务自动漂移 等等

为了解决上述问题,诞生了象 Spring Cloud 这样伟大的开发框架和系统。但这些能力都分布在各种 SDK 中,需要编写特定的代码进行操控,业务开发者需要理解整个框架,并熟悉周边的辅助系统。这些,无疑对开发者造成了困扰,提高了入门门槛。这个也造成了很多企业对于微服务改造的恐惧。

服务网格恰恰屏蔽了这些内容,将服务治理完全下沉到网络层。开发者无需再编写与业务无关的代码了。

“我只要写好 restful 的服务,丢到服务网格体系中,就 run 起来了,上面的那些能力自动获得。”

一个典型的服务网格应用示意如下图:

istio 架构
istio 架构

开发框架和组织的解耦

微服务通常由多个小组协同开发。在不了解服务网格的情况下,一般的企业技术决策者对于研发部门的能力考虑是单一技术栈,单一框架,考虑的出发点是技术栈可以保持延续,主要管理层可控(采用自己或心腹较擅长的技术)。并且如果企业大规模采用传统微服务开发,深入理解这些框架的大牛变得更加重要,一旦离开,后果便是灾难性的(如人人视频的 dubbo 大牛的离开)。

但在服务网格体系中,完全摆脱了技术栈和微服务框架的约束,允许开发者使用自己擅长的技术栈。企业决策者再也不必被某个核心技术人员掣肘,最难的服务治理问题已经被解决掉了。

服务网格对微服务的技术人员的要求和分工也带来了一些变化。通常的需求有两类:

  • 业务(服务)开发者:理解企业业务,并具有应用开发能力。按照上面的架构图,业务开发者写好 Service A 和 Service B 就好了。这部分角色的需求没有变化,本来在企业中就存在。
  • 运维开发:只需要理解容器,容器编排,以及服务网格/service mesh/isito,写一些部署脚本,或者把当前的 CI/CD 系统连接到服务网格就好了。这部分是需要新学习的内容,好在他足够简单,并且有云厂商的“贴身服务”。

当然,只要愿意,这两种角色可以合并,每个开发者都可以成为“技术大牛”。

但协调各个应用,仍然会需要约定,要求业务开发小组共同遵循。这些约定应该是适用所有微服务开发技术。

服务响应格式统一

在服务网格中,服务端一般采用 http 的 restful 的方式。统一的响应格式会为开发带来便利,也易于封装统一的调用。

下面是一个典型的响应封装:

代码语言:txt
复制
{
    "service": "passport",
    "timeStamp": 1559360704569,
    "success": true,
    "data": {
        "items": [
            {
                "id": 1,
                "title": "腾讯云",
            }
        ],
        "total": 1,
        "limit": 20,
        "offset": 0
    }
}

当然,为了通信效率,我们在服务之间调用可以使用其他的二进制 rpc 协议。在 istio 体系中,默认支持了谷歌自家的 gRPC。通过对 envoy filter 的扩展,还会支持更多的 RPC 协议,如 thift,dubbo 等。

远程访问的约定

通常对于OO类的语言,会屏蔽接口格式和通信协议,把这些约定写入开发框架或者 SDK 中,远程调用就像本地调用一样(如 java 的 feign),这样的好处很明显。但缺点也很明显:你被框架/SDK 绑定了。

服务网格中,Restful 服务间的调用采用的是 协议 (http or https) + 内部服务名/域名 + 端口 调用,如:http://passport.xyz.svc.cluster.local:7301/{your_api_url} 。在这里的一个较好的实践是:在配置文件中使用短服务名映射,屏蔽 http 协议 和 端口,并在部署的时候将这个配置放到远程配置中心。如:

代码语言:txt
复制
{
  "passport":"https://passport.xyz:7301/"
}

在应用中:

代码语言:txt
复制
//屏蔽协议,端口和域名
private String getRemote(String service, String url){
  String uri = Util.getServiceUrl(service) + url;
  return restTemplate.getForObject(uri, String.class);
}
代码语言:txt
复制
//调用上述方法
String result = getRemote("passport", "/open/account/info?ticket=xxx");

这样就可以屏蔽由于部署导致的协议,端口,和域名的变更。

服务的拆分和暴露

应用拆分的颗粒度问题:

  • 原子服务:基础的服务,与领域模型对应,直接与数据库打交道,包含增删改查等操作,此类服务只对内暴露。
  • 业务服务:对应前端具体的业务,具有业务逻辑,有可能与数据库打交道,也可能访问其他原子服务或业务服务。有些集成了安全认证的服务可以对外暴露。
  • 业务应用:直接面对最终用户的应用,可能包含UI,也可能是开放的API,必须包含安全认证。
  • 网关:通常会作为内部服务对外的出口,有安全认证,编排或协议转换等功能。

服务的拆分没有一定的规则,不同的架构师/开发者会有不同的拆分方法。

典型应用架构
典型应用架构

服务暴露通常会带来安全的挑战。

通常建议最小暴露,按需暴露。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 开发框架和组织的解耦
  • 服务响应格式统一
  • 远程访问的约定
  • 服务的拆分和暴露
相关产品与服务
服务网格
服务网格(Tencent Cloud Mesh, TCM),一致、可靠、透明的云原生应用通信网络管控基础平台。全面兼容 Istio,集成腾讯云基础设施,提供全托管服务化的支撑能力保障网格生命周期管理。IaaS 组网与监控组件开箱即用,跨集群、异构应用一致发现管理加速云原生迁移。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档