== Spring Cloud Alibaba Sidecar

`Spring Cloud Alibaba Sidecar` 是一个用来快速**完美整合** Spring Cloud
与 *异构微服务* 的框架，灵感来自
https://github.com/spring-cloud/spring-cloud-netflix/tree/master/spring-cloud-netflix-sidecar[Spring
Cloud Netflix Sidecar] 。目前支持的服务发现组件：

* Nacos
* Consul

=== 术语

==== 异构微服务

非Spring Cloud应用，统称异构微服务。比如你的遗留项目，或者非JVM应用。

==== ``完美整合''的三层含义

* 享受服务发现的优势
* 有负载均衡
* 有断路器

=== Why or Why not?

==== 为什么要编写Alibaba Sidecar？

原因有两点：

* Spring Cloud子项目 `Spring Cloud Netflix Sidecar`
是可以快速整合异构微服务的。然而，Sidecar只支持使用Eureka作为服务发现，*如果使用其他服务发现组件就抓瞎了*。
* *Sidecar是基于Zuul 1.x的*，Spring
Cloud官方明确声明，未来将会逐步淘汰Zuul。今年早些时候，我有给Spring
Cloud官方提出需求，希望官方实现一个基于Spring Cloud
Gateway的新一代Sidecar，然而官方表示并没有该计划。详见：https://github.com/spring-cloud/spring-cloud-gateway/issues/735

既然没有，索性自己写了。

==== 为什么不用Service Mesh？

* 目前Mesh主要使用场景在Kubernetes领域（Istio、Linkerd
2等，大多将Kubernetes作为First
Class支持，虽然Istio也可部署在非Kubernetes环境），而目前业界，Spring
Cloud应用未必有试试Mesh的环境；
* 使用Alibaba
Sidecar一个小组件就能解决问题了（核心代码不超过200行），引入整套Mesh方案，颇有点屠龙刀杀黄鳝的意思。

=== 原理

* Alibaba
Sidecar根据配置的异构微服务的IP、端口等信息，*将异构微服务的IP/端口注册到服务发现组件上*
。
* Alibaba Sidecar实现了 *健康检查* ，Alibaba
Sidecar会定时检测异构微服务是否健康。如果发现异构微服务不健康，Alibaba
Sidecar会自动将代表异构微服务的Alibaba
Sidecar实例下线；如果异构微服务恢复正常，则会自动上线。最长延迟是30秒，详见
`Alibaba SidecarChecker#check` 。

=== 要求

* 【必须】你的异构微服务需使用HTTP通信。这一点严格来说不算要求，因为Spring
Cloud本身就是基于HTTP的；
* 【可选】如果微服务配置了 `sidecar.health-check-url`
，则表示开启健康检查，此时，你的异构微服务需实现健康检查（可以是空实现，只要暴露一个端点，返回类似
`{"status": "UP"}` 的字符串即可）。

=== 使用示例

* 如使用Nacos作为服务发现组件，详见`spring-cloud-alibaba-examples/spring-cloud-alibaba-sidecar-examples/spring-cloud-alibaba-sidecar-nacos-example`
* 如使用Consul作为服务发现组件，详见`spring-cloud-alibaba-examples/spring-cloud-alibaba-sidecar-examples/spring-cloud-alibaba-sidecar-nacos-example`

==== 示例代码（以Nacos服务发现为例）

* 加依赖：
+
[source,xml]
----
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sidecar</artifactId>
</dependency>
----
* 写配置：
+
[source,yaml]
----
server:
  port: 8070
spring:
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
    gateway:
      discovery:
        locator:
          enabled: true
  application:
    name: node-service
sidecar:
  # 异构微服务的IP
  ip: 127.0.0.1
  # 异构微服务的端口
  port: 8060
  # 异构微服务的健康检查URL
  health-check-url: http://localhost:8060/health.json
management:
endpoint:
    health:
      show-details: always
----
+
配置比较简单，就是把Alibaba Sidecar注册到Nacos上，然后添加了几行Alibaba
Sidecar的配置。

==== 异构微服务

我准备了一个NodeJS编写的简单微服务。

[source,javascript]
----
var http = require('http');
var url = require("url");
var path = require('path');

// 创建server
var server = http.createServer(function(req, res) {
    // 获得请求的路径
    var pathname = url.parse(req.url).pathname;
    res.writeHead(200, { 'Content-Type' : 'application/json; charset=utf-8' });
    // 访问http://localhost:8060/，将会返回{"index":"欢迎来到首页"}
    if (pathname === '/') {
        res.end(JSON.stringify({ "index" : "欢迎来到首页" }));
    }
    // 访问http://localhost:8060/health，将会返回{"status":"UP"}
    else if (pathname === '/health.json') {
        res.end(JSON.stringify({ "status" : "UP" }));
    }
    // 其他情况返回404
    else {
        res.end("404");
    }
});
// 创建监听，并打印日志
server.listen(8060, function() {
    console.log('listening on localhost:8060');
});
----

==== 测试

===== 测试1：Spring Cloud微服务完美调用异构微服务

为你的Spring Cloud微服务整合Ribbon，然后构建 `http://node-service/**`
，就可以请求到异构微服务的 `/**` 了。

示例：

Ribbon请求 `http://node-service/` 会请求到 `http://localhost:8060/`
，以此类推。

至于断路器，正常为你的Spring
Cloud微服务整合Sentinel或者Hystirx、Resilience4J即可 。

===== 测试2：异构微服务完美调用Spring Cloud微服务

由于Alibaba Sidecar基于Spring Cloud Gateway，而网关自带转发能力。

示例：

如果你有一个Spring Cloud微服务叫做 `spring-cloud-microservice`
，那么NodeJS应用只需构建
`http://localhost:8070/spring-cloud-microservice/**` ，Alibaba
Sidecar就会把请求转发到 `spring-cloud-microservice` 的 `/**` 。

而Spring Cloud Gateway是整合了Ribbon的，所以实现了负载均衡；Spring Cloud
Gateway还可以整合Sentinel或者Hystirx、Resilience4J，所以也带有了断路器。

=== Alibaba Sidecar优缺点分析

Alibaba
Sidecar的设计和Sidecar基本一致，优缺点和Sidecar的优缺点也是一样的。

优点：

* 接入简单，几行代码就可以将异构微服务整合到Spring Cloud生态
* 不侵入原代码

缺点：

* 每接入一个异构微服务实例，都需要额外部署一个Alibaba
Sidecar实例，增加了部署成本（虽然这个成本在Kubernetes环境中几乎可以忽略不计（只需将Alibaba
Sidecar实例和异构微服务作为一个Pod部署即可））；
* 异构微服务调用Spring Cloud微服务时，本质是把Alibaba
Sidecar当网关在使用，经过了一层转发，性能有一定下降。
