服务迁移之路 | Spring Cloud向Service Mesh转变 | 技术干货


戳蓝字“CSDN云计算”关注我们哦!

640?wx_fmt=jpeg

技术头条:干货、简洁、多维全面。更多云计算精华知识尽在眼前,get要点、solve难题,统统不在话下!


作者: 李宁

转自:博云技术社区


Spring Cloud基于Spring Boot开发,提供一套完整的微服务解决方案,具体包括服务注册与发现,配置中心,全链路监控,API网关,熔断器,远程调用框架,工具客户端等选项中立的开源组件,并且可以根据需求对部分组件进行扩展和替换。


Service Mesh,这里以Istio(目前Service Mesh具体落地实现的一种,且呼声最高)为例简要说明其功能。 Istio 有助于降低这些部署的复杂性,并减轻开发团队的压力。它是一个完全开源的服务网格,可以透明地分层到现有的分布式应用程序上。它也是一个平台,包括允许它集成到任何日志记录平台、遥测或策略系统的 API。Istio的多样化功能集使你能够成功高效地运行分布式微服务架构,并提供保护、连接和监控微服务的统一方法。


从上面的简单介绍中,我们可以看出为什么会存在要把Spring Cloud体系的应用迁移到Service Mesh这样的需求,总结下来,有四方面的原因:


功能重叠

来简单看一下他们的功能对比:


功能列表Spring CloudIstio

服务注册与发现

支持,基于Eureka,consul等组件,提供server,和Client管理

支持,基于XDS接口获取服务信息,并依赖“虚拟服务路由表”实现服务发现

链路监控

支持,基于Zikpin或者Pinpoint或者Skywalking实现

支持,基于sideCar代理模型,记录网络请求信息实现

API网关

支持,基于zuul或者spring-cloud-gateway实现

支持,基于Ingress gateway以及egress实现

熔断器

支持,基于Hystrix实现

支持,基于声明配置文件,最终转化成路由规则实现

服务路由

支持,基于网关层实现路由转发

支持,基于iptables规则实现

安全策略

支持,基于spring-security组件实现,包括认证,鉴权等,支持通信加密

支持,基于RBAC的权限模型,依赖Kubernetes实现,同时支持通信加密

配置中心

支持,springcloud-config组件实现

不支持

性能监控

支持,基于Spring cloud提供的监控组件收集数据,对接第三方的监控数据存储

支持,基于SideCar代理,记录服务调用性能数据,并通过metrics adapter,导入第三方数据监控工具

日志收集

支持,提供client,对接第三方日志系统,例如ELK

支持,基于SideCar代理,记录日志信息,并通过log adapter,导入第三方日志系统

工具客户端集成

支持,提供消息,总线,部署管道,数据处理等多种工具客户端SDK

不支持

分布式事务

支持,支持不同的分布式事务模式:JTA,TCC,SAGA等,并且提供实现的SDK框架

不支持

其他

……

……


从上面表格中可以看到,如果从功能层面考虑,Spring Cloud与Service Mesh在服务治理场景下,有相当大量的重叠功能,从这个层面而言,为Spring Cloud向Service Mesh迁移提供了一种潜在的可能性。


服务容器化

在行业当前环境下,还有一个趋势,或者说是现状。越来越多的应用走在了通往应用容器化的道路上,或者在未来,容器化会成为应用部署的标准形态。而且无论哪种容器化运行环境,都天然支撑服务注册发现这一基本要求,这就导致Spring Cloud体系应用上容器的过程中,存在一定的功能重叠,有可能为后期的应用运维带来一定的影响,而Service Mesh恰恰需要依赖容器运行环境,同时弥补了容器环境所欠缺的内容(后续会具体分析)。


术业有专攻

从软件设计角度出发,我们一直在追求松耦合的架构,也希望做到领域专攻。例如业务开发人员希望我只要关心业务逻辑即可,不需要关心链路跟踪,熔断,服务注册发现等支撑工具的服务;而平台支撑开发人员,则希望我的代码中不要包含任何业务相关的内容。而Service Mesh的出现,让这种情况成为可能。


语言壁垒

目前而言Spring Cloud虽然提供了对众多协议的支持,但是受限于Java技术体系。这就要求应用需要在同一种语言下进行开发(这不一定是坏事儿),在某种情况下,不一定适用于一些工作场景。而从微服务设计考虑,不应该受限于某种语言,各个服务应该能够相互独立,大家需要的是遵循通信规范即可。而Service Mesh恰好可以消除服务间的语言壁垒,同时实现服务治理的能力。


基于以上四点原因,当下环境,除了部分大多已经提前走在了Service Mesh实践的道路上互联网大厂以外(例如蚂蚁金服的SOFASTACK),也有大部分企业已经开始接触Service Mesh,并且尝试把Spring Cloud构建的应用,迁移到Service Mesh中。



Spring Cloud向Service Mesh的迁移方案


Spring Cloud向Service Mesh迁移,从我们考虑而言大体分为七个步骤,如图所示:


640?wx_fmt=png


Spring Cloud架构解析

Spring Cloud架构解析的目的在于确定需要从当前的服务中去除与Service Mesh重叠的功能,为后续服务替换做准备。我们来看一个典型的Spring Cloud架构体系,如图所示:


640?wx_fmt=png


从图中我们可以简要的分析出,一个基于Spring Cloud的微服务架构,主要包括四部分内容:服务网关,应用服务,外围支撑组件,服务管理控制台。


  • 服务网关

    服务网关涵盖的功能包括路由,鉴权,限流,熔断,降级等对入站请求的统一拦截处理。具体可以进一步划分为外部网关(面向互联网)和内部网关(面向服务内部管理)。


  • 应用服务

    应用服务是企业业务核心。应用服务内部由三部分内容构成:业务逻辑实现,外部组件交互SDK集成,服务内部运行监控集成。


  • 外围支撑组件
    外围支撑组件,涵盖了应用服务依赖的工具,包括注册中心,配置中心,消息中心,安全中心,日志中心等。


  • 服务管理控制台
    服务管理控制台面向服务运维或者运营人员,实现对应用服务运行状态的实时监控,以及根据情况需要能够动态玩成在线服务的管理和配置。


这里面哪些内容是我们可以拿掉或者说基于Service Mesh(以Istio为例)能力去做的?分析下来,可以替换的组件包括网关(gateway或者Zuul,由Ingress gateway或者egress替换),熔断器(hystrix,由SideCar替换),注册中心(Eureka及Eureka client,由Polit,SideCar替换),负责均衡(Ribbon,由SideCar替换),链路跟踪及其客户端(Pinpoint及Pinpoint client,由SideCar及Mixer替换)。这是我们在Spring Cloud解析中需要完成的目标:即确定需要删除或者替换的支撑模块。


服务改造

服务单元改造的目的在于基于第一步的解析结果,完成依赖去除或者依赖替换。根据第一步的分析结果服务单元改造分为三步:

  1. 删除组件,包括网关,熔断器,注册中心,负载均衡,链路跟踪组件,同时删除对应client的SDK;

  2. 替换组件,采用httpClient 的SDK支持http协议的远程调用(原来在Ribbon中),由原来基于注册中心的调用,转变成http直接调用;

  3. 配置信息变更,修改与删除组件管理的配置信息以及必要的组件交互代码(根据实际应用情况操作);

当然服务单元改造过程中,还会涉及到很多的细节问题,都需要根据应用特点进行处理,这里不做深入分析。


服务容器化

服务容器化是目前应用部署的趋势所在。服务容器化本身有很多不同的方式,例如基于Jenkins的pipeline实现,基于docker-maven-plugin + dockerfile实现,当然还有很多不同的方式。这里以Spring Cloud一个demo服务通过docker-maven-plugin+dockerfile实现说明为例:


简易的一个服务的Dockerfile如下所示:


ROM openjdk:8-jre-alpineENV TZ=Asia/Shanghai \    SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \    JAVA_OPTS="" \    JHIPSTER_SLEEP=0RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezoneCMD echo "The application will start in ${JHIPSTER_SLEEP}s..." && \    sleep ${JHIPSTER_SLEEP} && \    java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /app.jar    # java ${JAVA_OPTS} -Djava.security.egd=environment:/dev/./urandom -jar /app.@project.packaging@EXPOSE 8080ADD microservice-demo.jar /app.jar
    SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
    JAVA_OPTS="" \
    JHIPSTER_SLEEP=0
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
CMD echo "The application will start in ${JHIPSTER_SLEEP}s..." && \
    sleep ${JHIPSTER_SLEEP} && \
    java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /app.jar
    # java ${JAVA_OPTS} -Djava.security.egd=environment:/dev/./urandom -jar /app.@project.packaging@

EXPOSE 8080
ADD microservice-demo.jar /app.jar


文件中定义了服务端口以及运行命令。


Maven-docker-plugin的插件配置如下所示:


<build>    <finalName>microservice-demo</finalName>    <plugins>        ......        <plugin>            <groupId>com.spotify</groupId>            <artifactId>docker-maven-plugin</artifactId>            <version>1.2.0</version>            <executions>                <execution>                    <id>build-image</id>                    <phase>package</phase>                    <goals>                        <goal>build</goal>                    </goals>                </execution>                <execution>                    <id>tag-image</id>                    <phase>package</phase>                    <goals>                        <goal>tag</goal>                    </goals>                    <configuration>                        <image>${project.build.finalName}:${project.version}</image>                        <newName>${docker.registry.name}/${project.build.finalName}:${project.version}</newName>                    </configuration>                </execution>                <!--暂时不添加推送仓库的配置-->            </executions>            <configuration>                <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>                <imageName>${project.build.finalName}:${project.version}</imageName>                <resources>                    <resource>                        <targetPath>/</targetPath>                        <directory>${project.build.directory}</directory>                        <include>${project.build.finalName}.${project.packaging}</include>                    </resource>                </resources>            </configuration>        </plugin>    </plugins></build>
    <finalName>microservice-demo</finalName>
    <plugins>
        ......
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>docker-maven-plugin</artifactId>
            <version>1.2.0</version>
            <executions>
                <execution>
                    <id>build-image</id>
                    <phase>package</phase>
                    <goals>
                        <goal>build</goal>
                    </goals>
                </execution>
                <execution>
                    <id>tag-image</id>
                    <phase>package</phase>
                    <goals>
                        <goal>tag</goal>
                    </goals>
                    <configuration>
                        <image>${project.build.finalName}:${project.version}</image>
                        <newName>${docker.registry.name}/${project.build.finalName}:${project.version}</newName>
                    </configuration>
                </execution>
                <!--暂时不添加推送仓库的配置-->
            </executions>
            <configuration>
                <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
                <imageName>${project.build.finalName}:${project.version}</imageName>
                <resources>
                    <resource>
                        <targetPath>/</targetPath>
                        <directory>${project.build.directory}</directory>
                        <include>${project.build.finalName}.${project.packaging}</include>
                    </resource>
                </resources>
            </configuration>
        </plugin>
    </plugins>
</build>


通过增加docker-maven-plugin,在执行mvn package的时候可以加载Dockerfile,自动构建服务的容器镜像(需要说明的前提是本地安装docker运行环境,或者通过环境变量在开发工具中配置Docker的远程连接环境),从而完成服务容器化改造。


容器环境构建

容器环境决定这Service Mesh的部署形态,这里不详细描述容器环境的部署过程。感兴趣的朋友,可以参考https://github.com/easzlab/kubeasz 开源项目,提供了Kubernetes基于ansible的自动化部署脚本。我们也建议选择Kubernetes来构建容器环境。这里说明容器环境构建的考虑因素:


1. 集群部署方案
集群部署方案主要考虑多集群,跨数据中心,存储选择,网络方案,集群内部主机标签划分,集群内部网络地址规划等多方面因素。


2. 集群规模
集群规模主要考虑etcd集群大小,集群内运行实例规模(用来配置ip范围段),集群高可用节点规模等因素。


基于以上两点来考虑容器化环境的部署方案,关键是合理规划,避免资源浪费。


Service Mesh环境构建

Service Mesh环境构建依赖于容器环境构建,主要考虑两个方面,以Isito为例:


1. 部署插件
Istio部署插件需要根据需要的场景,考虑采用的插件完整性,例如prometheus,kiali,是否开启TLS等,具体安装选项可以参考https://preliminary.istio.io/zh/docs/reference/config/installation-options/。


2. 跨集群部署
依据容器环境考虑是否需要支持Isito的跨集群部署方案.


服务注入

服务注入用于将容器化的服务接入到Service Mesh的平台中,目前主要有两种方式。以Isito为例说明,主要包括自动注入和手动入住。选择手动注入的目的在于可以根据企业内部上线流程,对服务接入进行人为控制。而自动注入则能够更加快捷,方便。到此实际上已经完成服务迁移工作。


服务管理控制台

由于Service Mesh目前而言,多是基于声明式的配置文件,达到服务治理的效果,因此无法实时传递执行结果。基于这种原因,需要一个独立的Service Mesh的管理控制台,一方面能够查看各个服务的运行状态以及策略执行情况,另外一方面能够支持服务运行过程中策略的动态配置管理。目前而言,可以在Isito安装过程中选择kiali作为一个控制台实现,当然未来也会有大量的企业提供专门的服务。


通过以上七个步骤,能够在一定程度上帮助企业应用,从Spring Cloud迁移到Service Mesh上,但迁移过程中必然存在不断踩坑的过程,需要根据应用特点,事前做好评估规划。



迁移优缺点分析


Spring Cloud迁移到Service Mesh是不是百利而无一害呢?


首先,从容器化的环境出发,后续Knative,Kubernetes,Service Mesh必然会构建出一套相对完整的容器化PaaS解决方案,从而完成容器化PaaS支撑平台的构建。Service Mesh将为容器运行态提供保驾护航的作用。


其次,就目前Service Mesh的落地实现而言,对于一些特定需求的监测粒度有所欠缺,例如调用线程栈的监测(当然,从网络层考虑,或者不在Service Mesh的考虑范围之内),但是恰恰在很多服务治理场景的要求范围之中。我们也需要针对这种情况,考虑实现方案。


最后,大家一直诟病的性能和安全问题。目前已经有所加强,但是依然被吐槽。


整体而言,Spring Cloud是微服务实现服务治理平台的现状,而Service Mesh却是未来,当然也不能完全取而代之,毕竟设计思路和侧重点不同,是否迁移需要根据业务场景而定。


640?wx_fmt=png

640?wx_fmt=jpeg


福利

扫描添加小编微信,备注“姓名+公司职位”,加入【云计算学习交流群】,和志同道合的朋友们共同打卡学习!


640?wx_fmt=jpeg


推荐阅读:

  • 如何快速深入理解监控知识? | 技术干货

  • 为什么说深耕AI领域绕不开知识图谱?

  • ARM 发布新一代 CPU 和 GPU,实现 20% 性能提升!

  • 比特币冲到9000美元, 你就能找个好工作?

  • 1000 万个“AI 名师”:用机器算法“解剖”应试教育

  • 阿里面试,我挂在了第四轮……

  • 10个爬虫工程师必备的工具了解一下


640?wx_fmt=png真香,朕在看了!

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

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

相关文章

oracle使用关键字做表字段名_ArcGIS SQL使用

本主题将介绍 ArcGIS 中的选择表达式所用的常规查询的各个元素。ArcGIS 中的查询表达式使用常规 SQL 语法。警告&#xff1a;SQL 语法不适用于使用字段计算器计算字段。字段在 SQL 表达式中指定字段时&#xff0c;如果该字段名可能产生岐义(比如与 SQL 保留关键字相同)&#xf…

uml类图浅录

uml类图UML中类图的绘制单个类图的绘制类图中的成员访问属性UML类图中类与类的几种关系关联代码示例解释UML类图表示多重性说明依赖代码示例解释uml类图表示继承示例代码解释UML类图表示实现示例代码解释UML类图表示聚合示例代码UML类图表示组合示例代码解释UML类图表示绘制UML…

03_SpringCloud整合Ribbon实现负载均衡

采用随机负载均衡策略&#xff0c;四线服务之间的调用 2个用户中心&#xff0c;1个内容中心&#xff0c;内容中心调用用户中心服务 package com.itmuch.contentcenter.service.impl;import com.itmuch.contentcenter.dao.content.ShareMapper; import com.itmuch.contentcent…

容器精华问答 | 我们为什么需要容器?

戳蓝字“CSDN云计算”关注我们哦&#xff01;容器技术是这两年热门的话题&#xff0c;因为容器技术给我们带来了很多方便的地方&#xff0c;节约了不少成本&#xff0c;不管是在运维还是开发上。今天&#xff0c;就让我们来看看关于容器更加有深度的问题吧。1Q&#xff1a;什么…

C++11继承构造函数在类中的使用

继承构造函数概念衍生问题使用示例注意扩展使用&#xff08;函数&#xff09;示例代码输出结果注意概念 继承构造函数在C11特性中随之提及&#xff0c;其大概可以理解为&#xff1a; 解决了派生类无法直接使用基类中的构造函数的这一问题。 正常情况下&#xff0c;基类定义了自…

grep从文件末尾开始找_新人自学前端到什么程度才能找工作?

这个问题打我记事起到现在&#xff0c;问过我的人&#xff0c;没有1000也有800了。足以见得这个问题是多么的不得人心。自学前端开发&#xff0c;不管他在网上百度了多少资料&#xff0c;看了多少教程&#xff0c;你总得先做个网页出来。所以&#xff0c;很多人都是从html标签开…

Spring Tool Suite 4安装Lombok

Lombok官网&#xff1a;https://www.projectlombok.org/download 文章目录一、下载jar包二、lombok.jar复制三、运行lombok.jar四、安装lombok4.1 点击确定4.2 找到SpringToolSuite4.exe五、以管理员运行Spring Tool Suite 4六、引入lombok依赖6.1 maven项目6.2 普通web项目七、…

base昆明,腾讯云在合作伙伴的阵营中@了TA

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;在今年的腾讯“三合一”大会上&#xff0c;阿晶得到了这样一则数据&#xff1a;截至目…

IntelliJ IDEA 2019 安装lombok

文章目录一、安装插件二、添加lombok依赖三、重启IntelliJ IDEA四、效果图五、如果不生效一、安装插件 二、添加lombok依赖 <!--Lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version&g…

记录C++类中的一次函数调用

引用 之前遇到一次函数调用结果的问题&#xff0c;今天在这里做一下记录。 一个基类&#xff0c;一个派生类&#xff0c;两个类中都有一个函数名相同&#xff0c;参数相同&#xff0c;参数不同的函数&#xff0c;创建基类指针指向派生类对象&#xff0c;调用相应的函数&#x…

bootstrap table移动端_bootstrap介绍

简介bootstrap是一款前端开发自适应页面的js库&#xff0c;可以让你在开发网页的时候轻松实现网站的PC与移动端兼容&#xff0c;避免在移动端上面出现样式错位等。原理bootstrap的原理是媒体查询CSS3的media&#xff0c;用于检测屏幕&#xff0c;从而改变样式的百分比。结构boo…

Spring Tool Suite 4 自动提示功能

文章目录一、java文件 自动提示二、JavaScript文件 自动提示三、HTML文件 自动提示四、导出配置文件五、编辑导出的配置文件5.1 java提示规则替换5.2 html提示规则替换六、导入配置好的文件一、java文件 自动提示 打开STS→Windows→Preferences→Java→Editor→Content Assis…

中立安全、赋能产业,UCloud优刻得凭差异化路线进军产业互联

2019年5月28日&#xff0c; 国内领先的中立云计算服务商UCloud优刻得&#xff08;以下简称UCloud&#xff09;在北京召开以“中立安全、赋能产业”为主题的UCloud用户大会暨Think in Cloud北京大会。面对走向纵深的产业互联网&#xff0c;UCloud强调做“不和用户竞争的云”&…

Spring Tool Suite 4 添加反编译插件

文章目录一、进入商店市场二、查找插件&#xff0c;输入jad搜索三、点击安装四、接收协议、安装五、重启Spring Tool Suite 4六、效果图一、进入商店市场 二、查找插件&#xff0c;输入jad搜索 三、点击安装 四、接收协议、安装 五、重启Spring Tool Suite 4 六、效果图

Hadoop精华问答 | NameNode是什么?

戳蓝字“CSDN云计算”关注我们哦&#xff01;2006年项目成立的一开始,“Hadoop”这个单词只代表了两个组件——HDFS和MapReduce。到现在的13个年头,这个单词代表的是“核心”&#xff0c;今天我们就来看看关于Hadoop的精华问答。1Q&#xff1a;NameNode是什么&#xff1f;A&…

01_SpringCoud 整合SpringCoud alibaba Nacos

SpringCoud 核心 整合SpringCoud alibaba Nacos 文章目录一、快速构建一个SpringBoot项目二、添加依赖2.1 SpringMVC2.2 nacos客户端2.3 lombok(可以省略)2.4 actuator监控(图形化)2.5 SpringCloud和spring-cloud-alibaba三、添加注解(无)四、写配置信息五、下载和运行nacos5.1…

C++线程处理函数的返回值

引言 关于线程处理函数&#xff0c;常见的可能是返回值为void类型&#xff0c;那线程处理函数是否能定义自己想要的返回值类型呢&#xff0c;这里请看下面的说明。 C线程返回值 应用环境1、传统的方式获取线程返回值2、使用C Promise和future方式3、promise和future介绍 应…

华为在欧注册HUAWEI ARK OS商标或为海外版操作系统命名;联通电信正探索合并?汽车共享品牌car2go近宣布退出中国……...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 一加 7 Pro &#xff…

ip访问次数统计 nginx_PHP实现IP访问限制及提交次数的方法详解

一、原理提交次数是肯定要往数据库里写次数这个数据的&#xff0c;比如用户登陆&#xff0c;当用户出错时就忘数据库写入出错次数1&#xff0c;并且出错时间&#xff0c;再出错写2&#xff0c;当满比如5次时提示不允许再登陆&#xff0c;请明天再试&#xff0c;然后用DateDiff计…

C++容器deque的用法

目录 1.deque容器概念 2.deque对象的构造 2.1deque对象的默认构造 2.2deque对象的带参数构造 3.deque头部和末尾的添加移除操作 4.deque的数据存取 5.deque与迭代器 6.deque的赋值 7.deque的大小 8.deque的插入 9.deque的删除 1.deque容器概念 deque容器概念 deque是…