替代SpringCloud,Istio好用到爆!

作者:微信小助手

发布时间:2022-07-02T17:16:59


文章来源:https://c1n.cn/Y55Wh


目录
  • 背景

  • 为什么要用Istio?

  • 编写部署文件

  • 部署应用到 Istio


背景


大家好,搞微服务也有好几年时间,从 16 年开始就一直关注微服务,到现在一直在使用的还是 SpringCloud 原生那套。


虽然后来出现了 SpringCloud Alibaba,但由于前面的所有系统框架都已定,就没有在变化。


而在微服务的实施过程,为了降运维的服务度,先后使用了 jenkins,docker, kubernetes 等,就还是没有使用过 Istio。基于这个原因,一直想尝试下开发基于 Istio 的 ServiceMesh 的应用。


正好最近受够了 SpringCloud 的“折磨”,对 Kubernetes 也可以熟练使用了,而且网上几乎没有 SpringBoot 微服务部署到 Istio 的案例,我就开始考虑用 SpringBoot 写个微服务的 Demo 并且部署到 Istio。


项目本身不复杂,就是发送一个字符串并且返回一个字符串的最简单的 Demo。


为什么要用 Istio?


目前,对于 Java 技术栈来说,构建微服务的最佳选择是 SpringBoot 而 SpringBoot 一般搭配目前落地案例很多的微服务框架 SpringCloud 来使用。


SpringCloud 看似很完美,但是在实际上手开发后,很容易就会发现 SpringCloud 存在以下比较严重的问题。


例如:

  • 服务治理相关的逻辑存在于 SpringCloud Netflix 等 SDK 中,与业务代码紧密耦合。

  • SDK 对业务代码侵入太大,SDK 发生升级且无法向下兼容时,业务代码必须做出改变以适配 SDK 的升级——即使业务逻辑并没有发生任何变化。

  • 各种组件令人眼花缭乱,质量也参差不齐,学习成本太高,且组件之间代码很难完全复用,仅仅为了实现治理逻辑而学习 SDK 也并不是很好的选择。

  • 绑定于 Java 技术栈,虽然可以接入其他语言但要手动实现服务治理相关的逻辑,不符合微服务“可以用多种语言进行开发”的原则。

  • SpringCloud 仅仅是一个开发框架,没有实现微服务所必须的服务调度、资源分配等功能,这些需求要借助 Kubernetes 等平台来完成。但 SpringCloud 与 Kubernetes 功能上有重合,且部分功能也存在冲突,二者很难完美配合。


替代 SpringCloud 的选择有没有呢?有!它就是 Istio。


Istio 彻底把治理逻辑从业务代码中剥离出来,成为了独立的进程(Sidecar)。部署时两者部署在一起,在一个 Pod 里共同运行,业务代码完全感知不到 Sidecar 的存在。


这就实现了治理逻辑对业务代码的零侵入——实际上不仅是代码没有侵入,在运行时两者也没有任何的耦合。


这使得不同的微服务完全可以使用不同语言、不同技术栈来开发,也不用担心服务治理问题,可以说这是一种很优雅的解决方案了。


所以,“为什么要使用 Istio”这个问题也就迎刃而解了——因为 Istio 解决了传统微服务诸如业务逻辑与服务治理逻辑耦合、不能很好地实现跨语言等痛点,而且非常容易使用。只要会用 Kubernetes,学习 Istio 的使用一点都不困难。


| 为什么要使用 gRPC 作为通信框架?

在微服务架构中,服务之间的通信是一个比较大的问题,一般采用 RPC 或者 RESTful API 来实现。


SpringBoot 可以使用 RestTemplate 调用远程服务,但这种方式不直观,代码也比较复杂,进行跨语言通信也是个比较大的问题。


而 gRPC 相比 Dubbo 等常见的 Java RPC 框架更加轻量,使用起来也很方便,代码可读性高,并且与 Istio 和 Kubernetes 可以很好地进行整合,在 Protobuf 和 HTTP2 的加持下性能也还不错。


所以这次选择了 gRPC 来解决 SpringBoot 微服务间通信的问题。并且,虽然 gRPC 没有服务发现、负载均衡等能力,但是 Istio 在这方面就非常强大,两者形成了完美的互补关系。


由于考虑到各种 grpc-spring-boot-starter 可能会对 SpringBoot 与 Istio 的整合产生不可知的副作用。


所以这一次我没有用任何的 grpc-spring-boot-starter,而是直接手写了 gRPC 与 SpringBoot 的整合。不想借助第三方框架整合 gRPC 和 Spring Boot 的可以简单参考一下我的实现。


| 编写业务代码

首先使用 Spring Initializr 建立父级项目 spring-boot-istio,并引入 gRPC 的依赖。


pom 文件如下:
<?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>spring-boot-istio-api</module>
        <module>spring-boot-istio-server</module>
        <module>spring-boot-istio-client</module>
    </modules>
    <parent>
        <groupId>org.springframework.boot</groupId> 
       <artifactId>spring-boot-starter-parent</artifactId> 
       <version>2.2.6.RELEASE</version>
       <relativePath/>
     </parent>
    <groupId>site.wendev</groupId>
    <artifactId>spring-boot-istio</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-istio</name>
    <description>Demo project for Spring Boot With Istio.</description>
    <packaging>pom</packaging>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.grpc</groupId>
                <artifactId>grpc-all</artifactId>
                <version>1.28.1</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>


然后建立公共依赖模块 spring-boot-istio-api,pom 文件如下,主要就是 gRPC 的一些依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <parent>
        <artifactId>spring-boot-istio</artifactId>
        <groupId>site.wendev</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>spring-boot-istio-api</artifactId>
    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-all</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version> 
       </dependency>
    </dependencies> 
   <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.6.2</version>
            </extension>
        </extensions>