Spring Cloud

Spring Clould Sidecar整合异构服务(Finc

2018-10-10  本文已影响32人  AaronSimon

本节我们主要讨论一下异构平台(比如,nodejs、python、php等提供的Rest接口服务)的服务,怎么通过spring cloud组件对这些服务注册到eureka中心以及与在微服务中怎么和异构平台的服务进行通信。这里主要是通过spring cloud的sidecar来构建异构平台的服务注册与通信。

sidecar灵感来自Netflix Prana。它可以获取注册中心的所有微服务实例的信息(例如host,端口等)的http api。也可以通过嵌入的Zuul代理来代理服务调用,该代理从Eureka获取其路由条目。 Spring Cloud配置服务器可以通过主机查找或通过嵌入的Zuul直接访问。

涉及到的服务如下:

服务名 端口 用途
eureka-server 8100 服务注册与发现
nodeSidecar 8130 异构服务对接服务
node 3000 nodejs服务
consumer 8106 消费者服务,与node服务存在声明式调用

1.1 Sidecar

1.1.1 Sidecar服务

先来看一下引入Sidecar需要做一些什么。

1. 添加 Maven 依赖,很简单,甚至不需要eureka-client的依赖,因为它已经整合至 Sidecar 的依赖中
<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-netflix-sidecar</artifactId>
    </dependency>
</dependencies>
2. 接下来是注解,在 Sidecar 主类上添加@EnableSidecar注解,我们来看看这个注解包含些什么
@EnableCircuitBreaker
@EnableZuulProxy
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(SidecarConfiguration.class)
public @interface EnableSidecar {

}

包含了网关 Zuul 以及微服务结构中不可或缺的熔断器 Hystrix

3. 最后是配置文件,在application.yml中添加如下配置
server:
  port: 8130
spring:
  application:
    name: nodeSidecar
eureka:
  instance:
    hostname: localhost
  client:
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:9090/eureka/
sidecar:
  port: 3000
  health-uri: http://localhost:${sidecar.port}/health

声明服务名和注册中心地址都没什么问题,最核心的就是 sidecar 的几个配置,包括

1.1.2 健康检查接口

需要注意的是:Node.js 的微服务应用必须实现一个/health健康检查接口,Sidecar 应用会每隔几秒访问一次该接口,并将该服务的健康状态返回给 Eureka,该接口只需要返回{ status: 'UP' }这样一串Json即可。


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' });
    if (pathname === '/index') {
        res.end(JSON.stringify({ "index" : "欢迎来到首页" }));
    }
    else if (pathname === '/health') {
        res.end(JSON.stringify({ "status" : "UP" }));
    }
    // 其他情况返回404
    else {
        res.end("404");
    }
});
// 创建监听,并打印日志
server.listen(3000, function() {
    console.log('listening on localhost:3000');
});

1.2 服务注册

准备好eureka,nodeSidecar,node服务。按顺序启动eureka->node服务->nodeSidecar

1.3 声明式服务调用

以上,我们已经验证了 Eureka 可以通过 Sidecar 间接的管理基于 Node 的微服务。而在微服务体系中,还有非常重要的一点,就是服务间的调用。Spring Cloud 允许我们使用服务名进行服务间的调用,摒弃了原先的固定写死的 IP 地址,便于服务集群的横向拓展及维护。那么,Non-JVM 的微服务与其他服务间是否可以通过服务名互相调用呢,答案是可以的。

1.3.1 被调用

我们假设下面一个场景,node服务提供了/index接口,返回json字符串。而 consumer服务需要访问node服务拿到返回的json数据。也就是 consumer服务需要访问 node服务 的/index接口拿到json字符串。

1. 在 node服务中实现/index接口,返回json字符串
// 创建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 === '/index') {
        res.end(JSON.stringify({ "index" : "欢迎来到首页" }));
    }
    // 访问http://localhost:8060/health,将会返回{"status":"UP"}
    else if (pathname === '/health') {
        res.end(JSON.stringify({ "status" : "UP" }));
    }
    // 其他情况返回404
    else {
        res.end("404");
    }
});
2. consumer作为 node 服务的调用者,需要声明 Client 接口,代码如下
@FeignClient("nodeSidecar")
public interface NodeServiceClient {
    @GetMapping("/index")
    String getIndex();
}

注意到@FeignClient注解中调用的服务名填写的是 nodeSidecar (大小写不敏感),因为自始至终 Eureka 中注册的是 Sidecar 的信息,而 Sidecar 实例维护了 node服务 的地址信息,所以它可以将请求转发至 node服务。

1.3.2 调用其它微服务

其他微服务可以通过 Sidecar 实例的服务名间接调用 Node 服务。同样的,node服务 也可以通过服务名调用其它微服务,这要归功于@EnableZuulProxy。

访问http://localhost:8130/consumer/index惊讶的发现,这和我们访问http://localhost:8106/index结果是一样的,这是由于 Sidecar 引入了 Zuul 网关,它可以获取 Eureka 上注册的服务的地址信息,从而进行路由跳转。因此,node访问其它微服务的地址格式为:http:localhost:8130/{serviceName}/method

另外,可以直接使用eureka的HTTP接口集成异构服务。由于eureka也是通过HTTP协议的接口暴露自身服务的,因此我们可以在node.js中手动发送HTTP请求实现服务的注册、查询和心跳功能。eureka接口描述信息可以在官方github的wiki中找到。但是这种方式存在弊端:

上一篇下一篇

猜你喜欢

热点阅读