开源 | Eggjs 和 SOFA 的跨语言互调

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: SOFARPC 是近期蚂蚁金服开源的一个高可扩展性、高性能、生产级的 Java RPC 框架。在蚂蚁金服 SOFARPC 已经经历了十多年及五代版本的发展。

原创声明:本文系作者原创,谢绝个人、媒体、公众号或网站未经授权转载,违者追究其法律责任。


SOFARPC 是近期蚂蚁金服开源的一个高可扩展性、高性能、生产级的 Java RPC 框架。在蚂蚁金服 SOFARPC 已经经历了十多年及五代版本的发展。SOFARPC 致力于简化应用之间的 RPC 调用,为应用提供方便透明、稳定高效的点对点远程服务调用方案。为了用户和开发者方便的进行功能扩展,SOFARPC 提供了丰富的模型抽象和可扩展接口,包括过滤器、路由、负载均衡等等。

伴随 SOFARPC 的开源,我们也开源了 sofa-bolt-node 和 sofa-rpc-node 两个 Nodejs RPC 基础模块。但细心的用户可能注意了我们在文档里面写到并不希望大家直接使用它们,并预告会在 Eggjs 里提供 RPC 最佳实践。

现在这个最佳实践来了,它就是:

egg-sofa-rpc 插件:

https://github.com/eggjs/egg-sofa-rpc

egg-rpc-generator 工具:

https://github.com/eggjs/egg-rpc-generator

本文通过 Step by Step 的形式介绍了 Eggjs 和 SOFA(Java)是如何进行互联互通的,涵盖了 RPC 的服务发现、接口定义、本地代理生成、服务端实现等各方面,期望展现给你一个相对完整的 Nodejs RPC 解决方案。考虑到社区的接受度、多语言友好性等因素,接下来的示例采用 protobuf 作为 RPC 的序列化方式。

一、准备工作

注意: 本文以 macOS 为例,其他操作系统的安装、使用方法请自行 google。

安装 nodejs >= 8.0.0

下载安装包:https://nodejs.org/en/download/

执行安装

安装 zookeeper
`
$ brew install zookeeper
`
启动 zookeeper 服务

$ zkServer start
ZooKeeper JMX enabled by default
Using config: /usr/local/etc/zookeeper/zoo.cfg
Starting zookeeper ... STARTED

克隆 SOFARPC Java 的示例仓库

SOFARPC 的更多信息可以参考官方文档

git clone git@github.com:gxcsoccer/sofa-rpc-java-demo.git

安装 egg-init
`
$ npm i egg-init -g
`

二、创建工程

通过 egg-init 初始化项目脚手架,选择 simple 模板,接下来根据实际情况填写必要信息

$ egg-init

? Please select a boilerplate type (Use arrow keys)
  ──────────────
 simple - Simple egg app boilerplate
  ts - Simple egg && typescript app boilerplate
  empty - Empty egg app boilerplate
  plugin - egg plugin boilerplate
  framework - egg framework boilerplate

进入生成好的项目目录,并安装依赖

$ cd /rpc-demo
$ npm i

安装 egg-sofa-rpc 插件和 egg-rpc-generator 工具

$ npm i egg-sofa-rpc --save
$ npm i egg-rpc-generator --save-dev

配置 package.json 的 scripts 节点,增加一个命令 rpc 如下

{
  "scripts": {
    "start": "egg-scripts start --daemon --title=egg-server-rpc-demo",
    "stop": "egg-scripts stop --title=egg-server-rpc-demo",
    "dev": "egg-bin dev",
    "debug": "egg-bin debug",
    "test": "npm run lint -- --fix && npm run test-local",
    "test-local": "egg-bin test",
    "cov": "egg-bin cov",
    "lint": "eslint .",
    "ci": "npm run lint && npm run cov",
    "autod": "autod",
    "rpc": "egg-rpc-generator"
  }
}

配置 config/plugin.js 开启 egg-sofa-rpc 插件

// config/plugin.js

exports.sofaRpc = {
  enable: true,
  package: 'egg-sofa-rpc'
};

三、定义接口

protobuf 有自己的接口定义语言,详细可以参考官方文档。

# ProtoService.proto 
syntax = "proto3";

package com.alipay.sofa.rpc.protobuf;
option java_multiple_files = true; // 可选
option java_outer_classname = "ProtoServiceModels"; // 可选

service ProtoService {
    rpc echoObj (EchoRequest) returns (EchoResponse) {}
}

message EchoRequest {
    string name = 1;
    Group group = 2;
}

message EchoResponse {
    int32 code = 1;
    string message = 2;
}

enum Group {
    A = 0;
    B = 1;
}

上面这个 ProtoService.proto 文件定义了一个服务:com.alipay.sofa.rpc.protobuf.ProtoService,它有一个叫 echoObj 的方法,入口参数类型是 EchoRequest,返回值类型是 EchoResponse。

四、调用 Java 暴露的 RPC 服务

1、启动 Java 服务端
进入上面克隆的 Java 示例仓库,运行 ProtobufServiceServerMain

2、配置服务发现参数
我们默认的服务发现依赖于 zookeeper,所以需要配置一个 zk 的地址。在 config/config.{env}.js 中配置如下:

// config/config.default.js
'use strict';

exports.sofaRpc = {
  registry: {
    address: '127.0.0.1:2181', // zk 地址指向本地 2181 端口
  }
};

3、获取接口定义
在 egg 项目根目录下创建 proto 目录,然后将上面定义的 ProtoService.proto 文件放到里

.
├── app
│   ├── controller
│   │   └── home.js
│   └── router.js
├── config
│   ├── config.default.js
│   └── plugin.js
├── package.json
└── proto
    └── ProtoService.proto

4、配置要调用的接口
在 config/proxy.js 中配置要调用的服务信息

'use strict';

module.exports = {
  services: [{
    appName: 'sofarpc',
    api: {
      ProtoService: 'com.alipay.sofa.rpc.protobuf.ProtoService',
    }
  }]
};

appName(必选): 服务提供方的应用名,如果没有可以任意起一个

api(必选): 接口列表,是一个 key-value 键值对,key 是生成的 proxy 文件名,value 是接口名(如果要跟精细的配置也可以是一个对象)

config/proxy.js 详细的配置说明可以参考文档

5、生成调用代理
在根目录下运行 npm run rpc,生成调用的 proxy 文件

$ npm run rpc
> rpc-demo@1.0.0 rpc /egg-rpc-demo
> egg-rpc-generator

[EggRpcGenerator] framework: /egg-rpc-demo/node_modules/egg, baseDir: /egg-rpc-demo
[ProtoRPCPlugin] found "com.alipay.sofa.rpc.protobuf.ProtoService" in proto file
[ProtoRPCPlugin] save all proto info into "/egg-rpc-demo/run/proto.json"

运行成功以后,会发现生成了两个文件

app/proxy/ProtoService.js - 调用服务的代理文件

run/proto.json - 从 .proto 文件中导出的接口信息,是一个 json 格式文件

.
├── app
│   ├── controller
│   │   └── home.js
│   ├── proxy
│   │   └── ProtoService.js
│   └── router.js
├── config
│   ├── config.default.js
│   ├── plugin.js
│   └── proxy.js
├── package.json
├── proto
│   └── ProtoService.proto
└── run
    └── proto.json

生成的 app/proxy/ProtoService.js 文件内容如下(注意:不要手动去改这个文件):

// Don't modified this file, it's auto created by egg-rpc-generator

'use strict';

const path = require('path');

/* eslint-disable */
/* istanbul ignore next */
module.exports = app => {
  const consumer = app.sofaRpcClient.createConsumer({
    interfaceName: 'com.alipay.sofa.rpc.protobuf.ProtoService',
    targetAppName: 'sofarpc',
    version: '1.0',
    group: 'SOFA',
    proxyName: 'ProtoService',
    responseTimeout: 3000,
  });

  if (!consumer) {
    // `app.config['sofarpc.rpc.service.enable'] = false` will disable this consumer
    return;
  }

  app.beforeStart(async() => {
    await consumer.ready();
  });

  class ProtoService extends app.Proxy {
    constructor(ctx) {
      super(ctx, consumer);
    }

    async echoObj(req) {
      return await consumer.invoke('echoObj', [ req ], { 
        ctx: this.ctx,
        codecType: 'protobuf',                                                
      });
    }
  }

  return ProtoService;
};
/* eslint-enable */

6、调用代理类,实现业务逻辑
上面定义的这个 ProtoService 这个类,会挂载在 app.proxyClasses 上。通过 ctx.proxy.protoService(注意这里是小驼峰)可以访问它的实例,这样我们就可以在业务中调用 RPC 的服务了,例如:下面我们在 home controller 调用 ProtoService 的 echoObj 方法

// app/controller/home.js

'use strict';

const Controller = require('egg').Controller;

class HomeController extends Controller {
  async index() {
    const { ctx } = this;
    const res = await ctx.proxy.protoService.echoObj({
      name: 'gxcsoccer',
      group: 'A',
    });
    ctx.body = res;
  }
}

module.exports = HomeController;

7、启动应用,调试

`
$ npm run dev
`
在浏览器中访问 http://127.0.0.1:7001/,得到下面的结果,说明成功了

五、暴露 RPC 服务给 Java 调用

这回换做 Nodejs 来暴露同样的服务,Java 端作为消费者

1、配置服务发现参数
和上面作为调用者的配置一样

// config/config.default.js

'use strict';

exports.sofaRpc = {
  registry: {
    address: '127.0.0.1:2181', // zk 地址指向本地 2181 端口
  }
};

2、定义接口
同样需要先定义接口,然后将 .proto 文件放到 proto 目录下,然后运行 npm run rpc,这些和上面作为调用者时都一样

3、配置 RPC 服务端的参数
通过 config/config.{env}.js 配置 RPC 服务端的参数

// config/config.default.js

'use strict';

exports.sofaRpc = {
  server: {
    namespace: 'com.alipay.sofa.rpc.protobuf'
  }
};

其中最主要的配置就是 namespace,其他配置都可以缺省:

namespace(必选): 接口的命名空间,所有的暴露的接口默认都在该命名空间下

selfPublish(可选): 是否每个 worker 进程独立暴露服务。nodejs 多进程模式下,如果多个进程共享一个端口,在 RPC 这种场景可能造成负载不均,所以 selfPublish 默认为 true,代表每个进程独立监听端口和发布服务

port(可选): 服务监听的端口(注意:在 selfPublish=true 时,监听的端口是基于这个配置生成的)

maxIdleTime(可选): 客户端连接如果在该配置时长内没有任何流量,则主动断开连接

responseTimeout(可选): 服务端建议的超时时长,具体的超时还是以客户端配置为准

codecType(可选): 推荐的序列化方式,默认为 protobuf

4、实现接口逻辑
在 app/rpc 目录下创建 ProtoService.js 文件,用于实现接口逻辑

'use strict';

exports.echoObj = async function(req) {
  return {
    code: 200,
    message: 'hello ' + req.name + ', you are in ' + req.group,
  };
};

5、启动应用,发布服务

$ npm run dev

6、Java 作为客户端调用服务
进入上面克隆的 Java 示例仓库,运行 ProtobufServiceClientMain

执行的结果如下:

Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Log4j2 ]
2018-06-11 18:07:59,977 INFO  [main] com.alipay.sofa.common.log:report:30 - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Log4j2 ]
2018-06-11 18:08:00,419 INFO  [main] org.apache.curator.framework.imps.CuratorFrameworkImpl:start:234 - Starting
2018-06-11 18:08:00,432 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT
2018-06-11 18:08:00,432 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:host.name=30.23.232.6
2018-06-11 18:08:00,432 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:java.version=1.8.0_171
2018-06-11 18:08:00,432 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:java.vendor=Oracle Corporation
2018-06-11 18:08:00,432 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:java.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre
2018-06-11 18:08:00,432 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:java.class.path=/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/lib/tools.jar:/Users/gaoxiaochen/projj/github.com/gxcsoccer/sofa-rpc-java-demo/target/classes:/Users/gaoxiaochen/.m2/repository/com/alipay/sofa/sofa-rpc-all/5.4.0/sofa-rpc-all-5.4.0.jar:/Users/gaoxiaochen/.m2/repository/com/alipay/sofa/bolt/1.4.1/bolt-1.4.1.jar:/Users/gaoxiaochen/.m2/repository/com/alipay/sofa/common/sofa-common-tools/1.0.12/sofa-common-tools-1.0.12.jar:/Users/gaoxiaochen/.m2/repository/org/slf4j/slf4j-api/1.7.21/slf4j-api-1.7.21.jar:/Users/gaoxiaochen/.m2/repository/org/javassist/javassist/3.20.0-GA/javassist-3.20.0-GA.jar:/Users/gaoxiaochen/.m2/repository/io/netty/netty-all/4.1.25.Final/netty-all-4.1.25.Final.jar:/Users/gaoxiaochen/.m2/repository/com/alipay/sofa/hessian/3.3.0/hessian-3.3.0.jar:/Users/gaoxiaochen/.m2/repository/com/alipay/sofa/tracer-core/2.1.1/tracer-core-2.1.1.jar:/Users/gaoxiaochen/.m2/repository/io/opentracing/opentracing-api/0.22.0/opentracing-api-0.22.0.jar:/Users/gaoxiaochen/.m2/repository/io/opentracing/opentracing-noop/0.22.0/opentracing-noop-0.22.0.jar:/Users/gaoxiaochen/.m2/repository/io/opentracing/opentracing-mock/0.22.0/opentracing-mock-0.22.0.jar:/Users/gaoxiaochen/.m2/repository/io/opentracing/opentracing-util/0.22.0/opentracing-util-0.22.0.jar:/Users/gaoxiaochen/.m2/repository/org/jboss/resteasy/resteasy-netty4/3.0.12.Final/resteasy-netty4-3.0.12.Final.jar:/Users/gaoxiaochen/.m2/repository/org/jboss/resteasy/resteasy-jaxrs/3.0.12.Final/resteasy-jaxrs-3.0.12.Final.jar:/Users/gaoxiaochen/.m2/repository/org/jboss/resteasy/jaxrs-api/3.0.12.Final/jaxrs-api-3.0.12.Final.jar:/Users/gaoxiaochen/.m2/repository/org/jboss/spec/javax/annotation/jboss-annotations-api_1.1_spec/1.0.1.Final/jboss-annotations-api_1.1_spec-1.0.1.Final.jar:/Users/gaoxiaochen/.m2/repository/javax/activation/activation/1.1.1/activation-1.1.1.jar:/Users/gaoxiaochen/.m2/repository/org/apache/httpcomponents/httpclient/4.3.6/httpclient-4.3.6.jar:/Users/gaoxiaochen/.m2/repository/org/apache/httpcomponents/httpcore/4.3.3/httpcore-4.3.3.jar:/Users/gaoxiaochen/.m2/repository/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar:/Users/gaoxiaochen/.m2/repository/commons-codec/commons-codec/1.6/commons-codec-1.6.jar:/Users/gaoxiaochen/.m2/repository/commons-io/commons-io/2.1/commons-io-2.1.jar:/Users/gaoxiaochen/.m2/repository/net/jcip/jcip-annotations/1.0/jcip-annotations-1.0.jar:/Users/gaoxiaochen/.m2/repository/org/jboss/resteasy/resteasy-client/3.0.12.Final/resteasy-client-3.0.12.Final.jar:/Users/gaoxiaochen/.m2/repository/org/jboss/resteasy/resteasy-jackson-provider/3.0.12.Final/resteasy-jackson-provider-3.0.12.Final.jar:/Users/gaoxiaochen/.m2/repository/org/codehaus/jackson/jackson-core-asl/1.9.12/jackson-core-asl-1.9.12.jar:/Users/gaoxiaochen/.m2/repository/org/codehaus/jackson/jackson-mapper-asl/1.9.12/jackson-mapper-asl-1.9.12.jar:/Users/gaoxiaochen/.m2/repository/org/codehaus/jackson/jackson-jaxrs/1.9.12/jackson-jaxrs-1.9.12.jar:/Users/gaoxiaochen/.m2/repository/org/codehaus/jackson/jackson-xc/1.9.12/jackson-xc-1.9.12.jar:/Users/gaoxiaochen/.m2/repository/com/alipay/sofa/lookout/lookout-api/1.4.0/lookout-api-1.4.0.jar:/Users/gaoxiaochen/.m2/repository/org/apache/curator/curator-recipes/2.9.1/curator-recipes-2.9.1.jar:/Users/gaoxiaochen/.m2/repository/org/apache/curator/curator-framework/2.9.1/curator-framework-2.9.1.jar:/Users/gaoxiaochen/.m2/repository/org/apache/curator/curator-client/2.9.1/curator-client-2.9.1.jar:/Users/gaoxiaochen/.m2/repository/org/apache/zookeeper/zookeeper/3.4.6/zookeeper-3.4.6.jar:/Users/gaoxiaochen/.m2/repository/log4j/log4j/1.2.16/log4j-1.2.16.jar:/Users/gaoxiaochen/.m2/repository/jline/jline/0.9.94/jline-0.9.94.jar:/Users/gaoxiaochen/.m2/repository/io/netty/netty/3.7.0.Final/netty-3.7.0.Final.jar:/Users/gaoxiaochen/.m2/repository/com/google/guava/guava/16.0.1/guava-16.0.1.jar:/Users/gaoxiaochen/.m2/repository/com/google/protobuf/protobuf-java/3.1.0/protobuf-java-3.1.0.jar:/Users/gaoxiaochen/.m2/repository/org/apache/logging/log4j/log4j-core/2.3/log4j-core-2.3.jar:/Users/gaoxiaochen/.m2/repository/org/apache/logging/log4j/log4j-api/2.3/log4j-api-2.3.jar:/Users/gaoxiaochen/.m2/repository/com/lmax/disruptor/3.3.7/disruptor-3.3.7.jar:/Users/gaoxiaochen/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.3/log4j-slf4j-impl-2.3.jar:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar
2018-06-11 18:08:00,432 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:java.library.path=/Users/gaoxiaochen/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
2018-06-11 18:08:00,433 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:java.io.tmpdir=/var/folders/q4/4nwl16wn32ndm69rzh1zyvhh0000gn/T/
2018-06-11 18:08:00,433 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:java.compiler=<NA>
2018-06-11 18:08:00,433 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:os.name=Mac OS X
2018-06-11 18:08:00,433 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:os.arch=x86_64
2018-06-11 18:08:00,433 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:os.version=10.13.4
2018-06-11 18:08:00,433 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:user.name=gaoxiaochen
2018-06-11 18:08:00,433 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:user.home=/Users/gaoxiaochen
2018-06-11 18:08:00,433 INFO  [main] org.apache.zookeeper.ZooKeeper:logEnv:100 - Client environment:user.dir=/Users/gaoxiaochen/projj/github.com/gxcsoccer/sofa-rpc-java-demo
2018-06-11 18:08:00,434 INFO  [main] org.apache.zookeeper.ZooKeeper:<init>:438 - Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=60000 watcher=org.apache.curator.ConnectionState@2e005c4b
2018-06-11 18:08:00,459 INFO  [main-SendThread(127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn:logStartConnect:975 - Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
2018-06-11 18:08:00,547 INFO  [main-SendThread(127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn:primeConnection:852 - Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
2018-06-11 18:08:00,555 INFO  [main-SendThread(127.0.0.1:2181)] org.apache.zookeeper.ClientCnxn:onConnected:1235 - Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x1000894bb75004f, negotiated timeout = 40000
2018-06-11 18:08:00,558 INFO  [main-EventThread] org.apache.curator.framework.state.ConnectionStateManager:postState:228 - State change: CONNECTED
2018-06-11 18:08:00,594 WARN  [main] org.apache.curator.utils.ZKPaths:<clinit>:76 - The version of ZooKeeper being used doesn't support Container nodes. CreateMode.PERSISTENT will be used instead.
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j2 ]
2018-06-11 18:08:00,645 INFO  [SOFA-CLI-CONN-com.alipay.sofa.rpc.protobuf.ProtoService-3-T1] com.alipay.sofa.common.log:report:30 - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j2 ]
2018-06-11 18:08:00,703 WARN No Root logger was configured, creating default ERROR-level Root logger with Console appender
/Users/gaoxiaochen/logs/tracelog/rpc-client-digest.log -> /Users/gaoxiaochen/logs/tracelog/rpc-client-digest.log.2018-06-09
200: hello zhang, you are in 0
200: hello zhang, you are in 0
200: hello zhang, you are in 0
200: hello zhang, you are in 0
200: hello zhang, you are in 0
200: hello zhang, you are in 0
200: hello zhang, you are in 0
200: hello zhang, you are in 0

相关资源链接:
SOFA Java Demo :

https://github.com/gxcsoccer/sofa-rpc-java-demo

Eggjs RPC Example :

https://github.com/eggjs/examples/tree/master/sofa-rpc

SOFARPC Node:

https://github.com/alipay/sofa-rpc-node

SOFABolt Node:

https://github.com/alipay/sofa-bolt-node

Eggjs:

https://eggjs.org

SOFARPC:

https://github.com/alipay/sofa-rpc

相关实践学习
基于MSE实现微服务的全链路灰度
通过本场景的实验操作,您将了解并实现在线业务的微服务全链路灰度能力。
目录
相关文章
|
7月前
|
编解码 Dubbo 应用服务中间件
Alibaba开源Dubbo源码解析手册,竟引领出RPC的新潮流
前言 Apache Dubbo,一款由阿里巴巴于2011年开源的高性能Java RPC框架,自开源以来在业界产生了深远影响。有大量公司广泛使用,甚至很多公司的自研RPC框架中都能看到Dubbo的影子。Dubbo在国内服务化体系演进过程中扮演了重要角色。尽管经历了几年的沉寂,但在阿里巴巴重启对Dubbo的开源维护,Dubbo正在从微服务领域的高性能RPC框架逐步演变为一个完整的微服务生态。 对于开发者来说,深入了解Dubbo底层的架构设计和实现是一项挑战。因此,一份完整的、体系化的对Apache Dubbo进行深入原理剖析的手册就显得尤为重要。
|
6月前
|
SQL 程序员 Go
Go语言微服务框架 - 7.Gormer-自动生成代码的初体验
作为一名程序员,我们总是希望能有更简单的开发方式来解决重复性的工作问题。在这个小版本中,我将结合自己的工作,来给出一套自动生成代码的完整方案,供大家借鉴。
40 0
|
2月前
|
监控 负载均衡 Dubbo
Dubbo 模块探秘:深入了解每个组件的独特功能【二】
Dubbo 模块探秘:深入了解每个组件的独特功能【二】
26 0
|
XML Java 数据格式
最近很火的SOFARPC是什么?带你快速入门SOFARPC
最近很火的SOFARPC是什么?带你快速入门SOFARPC
最近很火的SOFARPC是什么?带你快速入门SOFARPC
|
10月前
|
存储 JavaScript Linux
开源 Golang 微服务入门二:RPC 框架 Kitex| 青训营笔记
Kitex 字节跳动内部的 Golang 微服务 RPC 框架,具有高性能、强可扩展的特点,在字节内部已广泛使用。如果对微服务性能有要求,又希望定制扩展融入自己的治理体系,Kitex 会是一个不错的选
172 0
开源 Golang 微服务入门二:RPC 框架 Kitex| 青训营笔记
|
开发框架 监控 Dubbo
5 分钟读懂开源服务框架 Dubbo 及其最新规划
5 分钟读懂开源服务框架 Dubbo 及其最新规划
273 0
5 分钟读懂开源服务框架 Dubbo 及其最新规划
|
Rust 自然语言处理 Dubbo
Apache Dubbo 多语言体系再添新员:首个 Rust 语言版本正式发布
> 欢迎通过以下方式参与 Dubbo Rust 社区: > - 搜索并关注 Apache Dubbo 微信公众号了解社区最新动态 > - 直接到 GitHub 提交 Issue 或贡献代码 https://github.com/apache/dubbo-rust 近日,Apache Dubbo 发布了其 Rust 语言实现的首个版本,进一步丰富其多语言体系,这是社区全面对齐 Dubbo3
281 1
|
XML SpringCloudAlibaba Dubbo
硬核 | 我一个人开发了“Dubbo”框架
大家好,我是冰河~~ 没错,这次冰河又要搞事情了,这次准备下手的是RPC框架项目。为什么要对RPC框架项目下手呢,因为在如今分布式、微服务乃至云原生不断发展的过程中,RPC作为底层必不可少的通信组件,被广泛应用在分布式、微服务和云原生项目中。
123 0
硬核 | 我一个人开发了“Dubbo”框架
|
负载均衡 Dubbo 应用服务中间件
蚂蚁金服开源-SofaRpc源码学习篇
一个service,一个client,一个注册中心。 service注册自己到registry注册中心,包括service-name,还有相应的ip,port,然后client去监听注册中心,然后拿到service的地址,调用的时候会通过生成一个代理,去invoke调用结果返回
739 0
蚂蚁金服开源-SofaRpc源码学习篇
|
JSON 负载均衡 监控
2021-Java后端工程师必会知识点-(分布式RPC框架Dubbo)
前言 文本已收录至我的GitHub仓库,欢迎Star:github.com/bin39232820… 种一棵树最好的时间是十年前,其次是现在
215 0