扫码关注公众号:芋道源码

发送: 百事可乐
获取永久解锁本站全部文章的链接

《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 https://www.jianshu.com/p/1eeee833bd5d 「鋒Nic」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

简介摘要

SOFA 是蚂蚁金服自主研发的金融级分布式中间件,包含构建金融级云原生架构所需的各个组件,包括微服务研发框架,RPC 框架,服务注册中心,分布式定时任务,限流/熔断框架,动态配置推送,分布式链路追踪,Metrics监控度量,分布式高可用消息队列,分布式事务框架,分布式数据库代理层等组件,是一套分布式架构的完整的解决方案,也是在金融场景里锤炼出来的最佳实践。 SOFARPC是蚂蚁金服开源的高可扩展性、高性能、生产级的Java RPC框架。SOFARPC致力于简化应用之间的RPC调用,为应用提供方便透明、稳定高效的点对点远程服务调用方案。为了用户和开发者方便的进行功能扩展,SOFARPC提供丰富的模型抽象和可扩展接口,包括过滤器、路由、负载均衡等等。 SOFARPC功能特性:(1)透明化、高性能的远程服务调用;(2)支持多种服务路由及负载均衡策略;(3)支持多种注册中心的集成;(4)支持多种协议;(5)支持同步、单向、回调、泛化等多种调用方式;(6)支持集群容错、服务预热、自动故障隔离;(7)强大的扩展功能,可以按需扩展各个功能组件。 SOFARPC Github:https://github.com/alipay/sofa-rpc 架构设计 SOFARPC从下到上分为两层:核心层:包含RPC 的核心组件(例如我们的各种接口、API、公共包)以及一些通用的实现(例如随机等负载均衡算法)。功能实现层:所有的功能实现层的用户都是平等的,都是基于扩展机制实现的。

img

架构组件

img

框架原理

SOFARPC源码主要模块包括all(发布打包模块),bom(依赖管控模块,用于依赖版本管控),example(示例模块),test(测试模块,包含集成测试),core(api:API模块,涵盖各种基本流程接口、消息、上下文、扩展接口等;common:common 公共模块,涵盖工具类utils、数据结构;exception:异常模块,涵盖各种异常接口接口等)。其中core模块包括bootstrap(启动实现模块,用于启动类,发布或者引用服务逻辑、以及registry的操作),proxy(代理实现模块,用于接口实现代理生成),client(客户端实现模块,用于发送请求、接收响应、连接维护、路由、负载均衡、同步异步等),server(服务端实现模块,用于启动监听、接收请求,发送响应、业务线程分发等),filter(拦截器实现模块,用于服务端和客户端的各种拦截器实现),codec(编解码实现模块,例如压缩,序列化等),protocol(协议实现模块,用于协议的包装处理、协商),transport(网络传输实现模块,用于TCP连接的建立,数据分包粘包处理,请求响应对象分发等),registry(注册中心实现模块 实现注册中心,例如zk等)。

img

源码模块

img

项目结构

SOFA RPC提供应用之间的点对点服务调用功能,具有高可伸缩性、高容错性的特性。为了保证高可用性,通常同一个应用或同一个服务的提供方都会部署多份,以达到对等服务的目标。SOFA RPC提供软件负载的能力,它是对等服务调用的调度器,它会帮助服务的消费方在这些对等的服务提供方中合理地选择一个来执行相关的业务逻辑。为了保证应用的高容错性,需要服务消费方能够感知服务提供方的异常,并做出相应的处理,以减少应用出错后导致的服务调用抖动。在SOFA RPC中,一切服务调用的容错机制均由软负载和配置中心控制,这样可以在应用系统无感知的情况下,帮助服务消费方正确选择健康的服务提供方,保障全站的稳定性。

实现原理

SOFA RPC远程调用是通过服务模型来定义服务调用双方的,服务分为服务消费方和服务提供方,对应 RPC 的调用端和被调用端,可以理解为调用客户端和服务端。服务提供方称之为服务(service),服务消费方称之为引用(reference)。

SOFA RPC服务发布、引用以及调用的流程如图所示:

(1)当SOFA RPC的应用启动的时候,如果发现当前应用需要发布RPC 服务的话,那么SOFA RPC会将这些服务注册到配置中心上,就是图中蓝线所示的过程;

(2)当引用这个服务的SOFA应用启动时,会从配置中心订阅对应服务的地址;

(3)当配置中心收到订阅请求后,会将发布方的地址列表推送给订阅方,就是图中绿线所示的过程;

(4)当引用服务的一方拿到地址以后,就可以发起直连调用服务,就是图中蓝色虚线的部分。

img

实现原理

img

客户端调用流程

img

服务端处理流程

img

扩展点加载

搭建环境

SOFARPC包括SOFARPC方式和SOFABoot方式编程界面。

SOFARPC方式参考示例:

https://github.com/alipay/sofa-rpc/tree/master/example

SOFABoot方式参考示例:

https://github.com/alipay/sofa-boot/tree/master/sofaboot-samples/sofaboot-sample-with-rpc

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

SOFARPC方式

(1)创建工程

新建Maven工程sofa-rpc-demo,通过pom.xml文件引入SOFARPC的依赖:

<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofa-rpc-all</artifactId>
<version>5.3.1</version>
</dependency>

(2)编写服务提供端 第一步:创建服务端接口

package org.alipay.sofa.rpc;

public interface HelloService {

/**
* Just say hello
*
* @param name Name
* @return response
*/
public String sayHello(String name);
}

第二步:创建服务端接口实现

package org.alipay.sofa.rpc;

public class HelloServiceImpl implements HelloService {

@Override
public String sayHello(String name) {
System.out.println("Server receive: " + name);
return "hello " + name + " !";
}
}

第三步:编写服务端代码

package org.alipay.sofa.rpc;

import com.alipay.sofa.rpc.config.ProviderConfig;
import com.alipay.sofa.rpc.config.ServerConfig;

public class RpcServer {

public static void main(String[] args) {
ServerConfig serverConfig = new ServerConfig()
.setProtocol("bolt") // 设置一个协议,默认bolt
.setPort(12200) // 设置一个端口,默认12200
.setDaemon(false); // 非守护线程

ProviderConfig<HelloService> providerConfig = new ProviderConfig<HelloService>()
.setInterfaceId(HelloService.class.getName()) // 指定接口
.setRef(new HelloServiceImpl()) // 指定实现
.setServer(serverConfig); // 指定服务端

providerConfig.export(); // 发布服务
}
}

(3)编写服务调用端 第一步:获取服务端接口 服务端通过jar的形式将接口类提供给客户端,通过pom.xml文件引入服务提供端依赖:

<dependency>
<groupId>org.alipay.sofa</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>

第二步:编写客户端代码

package org.alipay.sofa.rpc;

import com.alipay.sofa.rpc.config.ConsumerConfig;

public class RpcClient {

public static void main(String[] args) {

ConsumerConfig<HelloService> consumerConfig = new ConsumerConfig<HelloService>()
.setInterfaceId(HelloService.class.getName()) // 指定接口
.setProtocol("bolt") // 指定协议
.setDirectUrl("bolt://127.0.0.1:12200") // 指定直连地址
.setConnectTimeout(10 * 1000);

HelloService helloService = consumerConfig.refer();

while (true) {
try {
System.out.println(helloService.sayHello("world"));
} catch (Exception e) {
e.printStackTrace();
}

try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}

}
}
}

(4)运行服务 分别启动服务端和客户端,观察运行效果。首先运行服务提供端程序 RpcServer,服务提供端日志输出如下:

2018-05-07 00:13:29,065 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180427231325, PID is:9876
2018-05-07 00:13:30,139 main INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-05-07 00:13:30,779 main INFO [com.alipay.sofa.rpc.bootstrap.DefaultProviderBootstrap:infoWithApp:122] - Export provider config : com.alipay.sofa.rpc.quickstart.HelloService: with bean id rpc-cfg-0
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-05-07 00:13:32,707 main INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]

接着运行服务调用端程序RpcClient,服务调用端日志输出如下:

2018-05-07 00:16:03,775 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180427231325, PID is:6524
2018-05-07 00:16:03,851 main INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-05-07 00:16:04,151 main INFO [com.alipay.sofa.rpc.bootstrap.DefaultConsumerBootstrap:infoWithApp:122] - Refer consumer config : bolt://com.alipay.sofa.rpc.quickstart.HelloService: with bean id rpc-cfg-0
2018-05-07 00:16:05,343 main INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - Add provider of com.alipay.sofa.rpc.quickstart.HelloService, size is : 1
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-05-07 00:16:06,060 SOFA-CLI-CONN-com.alipay.sofa.rpc.quickstart.HelloService-3-T1 INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-05-07 00:16:08,297 SOFA-CLI-CONN-com.alipay.sofa.rpc.quickstart.HelloService-3-T1 INFO [com.alipay.sofa.rpc.client.AllConnectConnectionHolder:infoWithApp:122] - Connect to com.alipay.sofa.rpc.quickstart.HelloService provider:bolt://127.0.0.1:12200 success ! The connection is 127.0.0.1:12200 <-> 127.0.0.1:50836
hello world !
hello world !

最后检查服务提供端接收消息情况,服务提供端日志输出如下:

2018-05-07 00:13:29,065 main  INFO [com.alipay.sofa.rpc.context.RpcRuntimeContext:info:102] - Welcome! Loading SOFA RPC Framework : 5.4.0_20180427231325, PID is:9876
2018-05-07 00:13:30,139 main INFO [com.alipay.sofa.rpc.module.ModuleFactory:info:102] - Install Module: fault-tolerance
2018-05-07 00:13:30,779 main INFO [com.alipay.sofa.rpc.bootstrap.DefaultProviderBootstrap:infoWithApp:122] - Export provider config : com.alipay.sofa.rpc.quickstart.HelloService: with bean id rpc-cfg-0
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
2018-05-07 00:13:32,707 main INFO [com.alipay.sofa.common.log:report:30] - Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Log4j ]
Server receive: world
Server receive: world

SOFABoot方式

SOFABoot是蚂蚁金服开源的基于 Spring Boot 的研发框架,它在Spring Boot的基础上,提供诸如 Readiness Check,类隔离,日志空间隔离等等能力。在增强Spring Boot的同时,SOFABoot提供让用户可以在Spring Boot中非常方便地使用SOFA中间件的能力。 (1)创建工程 工程构建:SOFABoot构建在Spring Boot之上,使用Spring Boot 的工程生成工具来生成标准的Spring Boot 工程,新建工程sofa-rpc-boot-demo。

构建项目

引入SOFABoot依赖:SOFABoot提供如健康检查,上下文隔离等基础能力,同时提供多种中间件进行选择使用。SOFABoot对提供这些能力的依赖利用如下pom进行管控,将工程的parent设为该pom:

<parent>
<groupId>com.alipay.sofa</groupId>
<artifactId>sofaboot-dependencies</artifactId>
<version>2.3.2</version>
</parent>

引入SOFARPC Starter:SOFARPC Starter是SOFARPC基于SOFABoot实现的框架,能够将SOFARPC的能力以统一的编程界面和简单的操作形式提供给使用者。该依赖已被 SOFABoot管控,pom.xml文件需要引入如下依赖:

<dependency>
<groupId>com.alipay.sofa</groupId>
<artifactId>rpc-sofa-boot-starter</artifactId>
</dependency>

配置应用:application.properties是SOFABoot工程中的配置文件。配置 application.properties 需要配置一个必不可少的配置项,即应用名,并且需要将application.properties中的com.alipay.sofa.rpc.registry.address 配置注释掉.指定走本地文件注册中心的方式:

spring.application.name=sofa-rpc-boot-demo
#com.alipay.sofa.rpc.registry.address=zookeeper://127.0.0.1:2181

声明SOFABoot的xsd文件:声明 SOFABoot的xsd文件在要使用的XML配置文件中将头部 xsd 文件的声明如下设置,这样就能够使用 SOFABoot 定义的 XML 元素进行开发:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sofa="http://sofastack.io/schema/sofaboot"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd"
default-autowire="byName">

(2)编写服务提供端 第一步:创建服务端接口

package org.alipay.sofa.rpc;

public interface HelloSyncService {

String saySync(String string);
}

第二步:创建服务端接口实现

package org.alipay.sofa.rpc;

public class HelloSyncServiceImpl implements HelloSyncService {

@Override
public String saySync(String string) {
return string;
}
}

第三步:服务端发布服务 新建src/main/resource/sofa-rpc-server.xml文件,在xml文件中编写如下配置。Spring上下文在刷新时,SOFABoot就将该服务实现注册到了服务器上,以bolt协议与客户端进行通信地址,并将地址等元数据发布到了注册中心,默认使用的本地文件作为注册中心:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sofa="http://sofastack.io/schema/sofaboot"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd">

<!-- invoke sync-->
<bean id="helloSyncServiceImpl" class="com.alipay.sofa.rpc.HelloSyncServiceImpl"/>
<sofa:service ref="helloSyncServiceImpl" interface="com.alipay.sofa.rpc.HelloSyncService">
<sofa:binding.bolt/>
</sofa:service>
</beans>

(3)编写服务调用端 第一步:获取服务端接口 服务端通过jar的形式将接口类提供给客户端,通过pom.xml文件引入服务提供端依赖:

<dependency>
<groupId>org.alipay.sofa</groupId>
<artifactId>provider</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>

第二步:客户端引用服务 新建src/main/resource/sofa-rpc-client.xml文件,在xml文件中编写如下配置。Spring上下文刷新时,SOFABoot会生成一个RPC的代理 bean,即helloSyncServiceReference。这样就可以直接在代码中使用该 bean 进行远程调用:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sofa="http://sofastack.io/schema/sofaboot"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://sofastack.io/schema/sofaboot http://sofastack.io/schema/sofaboot.xsd">

<!-- invoke sync-->
<sofa:reference id="helloSyncServiceReference" interface="com.alipay.sofa.rpc.HelloSyncService">
<sofa:binding.bolt/>
</sofa:reference>
</beans>

其中reference元素表示引用该服务,binding元素声明该服务引用的调用的协议。 (4)运行服务 改造默认启动类,在 SpringBoot 的启动类中编码如下,其中利用 ImportResource 将上述的xml文件加载。 服务提供端启动类:

package org.alipay.sofa.rpc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;

@ImportResource({"classpath:sofa-rpc-server.xml"})
@SpringBootApplication
public class ServerProviderApplication {

public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(ServerProviderApplication.class);
ApplicationContext applicationContext = springApplication.run(args);
}
}

服务调用端启动类:

package org.alipay.sofa.rpc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.ImportResource;

@ImportResource({"classpath:sofa-rpc-client.xml"})
@SpringBootApplication
public class ClientConsumerApplication {

public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(ClientConsumerApplication.class);
ApplicationContext applicationContext = springApplication.run(args);

HelloSyncService helloSyncServiceReference = (HelloSyncService) applicationContext
.getBean("helloSyncServiceReference");
System.out.println(helloSyncServiceReference.saySync("sync"));
}
}

运行服务提供端启动类ServerProviderApplication 查看提供端运行效果,服务提供端输出日志如下:

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.2.RELEASE)

Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
2018-05-07 02:26:38.972 INFO 14136 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
2018-05-07 02:26:39.004 INFO 14136 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-05-07 02:26:39.367 INFO 14136 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-05-07 02:26:39.551 INFO 14136 --- [ main] c.a.s.r.s.d.ServerProvierApplication : Starting ServerProvierApplication on LBDZ-20120729HW with PID 14136 (D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes started by Administrator in D:\Program\Github\sofa-rpc-boot-projects)
2018-05-07 02:26:39.552 INFO 14136 --- [ main] c.a.s.r.s.d.ServerProvierApplication : No active profile set, falling back to default profiles: default
2018-05-07 02:26:39.846 INFO 14136 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@14dd9eb7: startup date [Mon May 07 02:26:39 CST 2018]; root of context hierarchy
2018-05-07 02:26:41.873 INFO 14136 --- [ main] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [sofa-rpc-client.xml]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-05-07 02:26:42.459 INFO 14136 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-05-07 02:26:42.712 INFO 14136 --- [ main] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [sofa-rpc-server .xml]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-05-07 02:26:43.934 INFO 14136 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
2018-05-07 02:26:45.805 INFO 14136 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-05-07 02:26:46.025 INFO 14136 --- [ectService-3-T1] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-05-07 02:26:46.970 INFO 14136 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-05-07 02:26:47.026 INFO 14136 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2018-05-07 02:26:47.028 INFO 14136 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.6
2018-05-07 02:26:47.328 INFO 14136 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-05-07 02:26:47.328 INFO 14136 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 7482 ms
2018-05-07 02:26:47.822 INFO 14136 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-05-07 02:26:47.829 INFO 14136 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'metricsFilter' to: [/*]
2018-05-07 02:26:47.830 INFO 14136 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-05-07 02:26:47.830 INFO 14136 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-05-07 02:26:47.830 INFO 14136 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-05-07 02:26:47.831 INFO 14136 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-05-07 02:26:47.831 INFO 14136 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'webRequestLoggingFilter' to: [/*]
2018-05-07 02:26:47.831 INFO 14136 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'applicationContextIdFilter' to: [/*]
2018-05-07 02:26:48.658 INFO 14136 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@14dd9eb7: startup date [Mon May 07 02:26:39 CST 2018]; root of context hierarchy
2018-05-07 02:26:48.755 INFO 14136 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-05-07 02:26:48.757 INFO 14136 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-05-07 02:26:48.810 INFO 14136 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-07 02:26:48.810 INFO 14136 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-07 02:26:48.923 INFO 14136 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-07 02:26:49.506 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/health || /health.json],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(java.security.Principal)
2018-05-07 02:26:49.510 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/info || /info.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.511 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.513 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2018-05-07 02:26:49.513 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.515 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.517 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/sofaboot/versions || /sofaboot/versions.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.518 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.524 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2018-05-07 02:26:49.524 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.525 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/logfile || /logfile.json],methods=[GET || HEAD]}" onto public void org.springframework.boot.actuate.endpoint.mvc.LogFileMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2018-05-07 02:26:49.526 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.527 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException
2018-05-07 02:26:49.527 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/health/readiness || /health/readiness.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.healthcheck.service.SofaBootReadinessCheckMvcEndpoint.invoke(java.security.Principal)
2018-05-07 02:26:49.528 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.529 INFO 14136 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:26:49.762 INFO 14136 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-05-07 02:26:49.786 INFO 14136 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2018-05-07 02:26:50.878 INFO 14136 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-05-07 02:26:50.891 INFO 14136 --- [ main] c.a.s.r.s.d.ServerProvierApplication : Started ServerProvierApplication in 14.713 seconds (JVM running for 21.842)

运行服务调用端启动类ClientConsumerApplication 查看调用端运行效果,服务调用端输出日志如下:

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.2.RELEASE)

Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
2018-05-07 02:37:04.863 INFO 12900 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual logging.path is [ ./logs ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
2018-05-07 02:37:04.881 INFO 12900 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.infra Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-05-07 02:37:05.520 INFO 12900 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.healthcheck Logback ]
2018-05-07 02:37:05.583 INFO 12900 --- [ main] c.a.s.r.s.d.ClientConsumerApplication : Starting ClientConsumerApplication on LBDZ-20120729HW with PID 12900 (D:\Program\Github\sofa-rpc-boot-projects\sofa-boot-samples\target\classes started by Administrator in D:\Program\Github\sofa-rpc-boot-projects)
2018-05-07 02:37:05.584 INFO 12900 --- [ main] c.a.s.r.s.d.ClientConsumerApplication : No active profile set, falling back to default profiles: default
2018-05-07 02:37:05.682 INFO 12900 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@5fe94a96: startup date [Mon May 07 02:37:05 CST 2018]; root of context hierarchy
2018-05-07 02:37:07.835 INFO 12900 --- [ main] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [sofa-rpc-server.xml]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-05-07 02:37:08.234 INFO 12900 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc.boot Logback ]
2018-05-07 02:37:08.339 INFO 12900 --- [ main] o.s.b.f.xml.XmlBeanDefinitionReader : Loading XML bean definitions from class path resource [sofa-rpc-client.xml]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
2018-05-07 02:37:09.738 INFO 12900 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.runtime Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
2018-05-07 02:37:10.476 INFO 12900 --- [ main] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.sofa.rpc Logback ]
Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-05-07 02:37:10.746 INFO 12900 --- [ectService-3-T1] com.alipay.sofa.common.log : Sofa-Middleware-Log SLF4J : Actual binding is of type [ com.alipay.remoting Logback ]
2018-05-07 02:37:12.152 INFO 12900 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8081 (http)
2018-05-07 02:37:12.176 INFO 12900 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2018-05-07 02:37:12.178 INFO 12900 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.6
2018-05-07 02:37:12.559 INFO 12900 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-05-07 02:37:12.559 INFO 12900 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 6877 ms
2018-05-07 02:37:13.272 INFO 12900 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-05-07 02:37:13.284 INFO 12900 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'metricsFilter' to: [/*]
2018-05-07 02:37:13.285 INFO 12900 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-05-07 02:37:13.285 INFO 12900 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-05-07 02:37:13.285 INFO 12900 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-05-07 02:37:13.286 INFO 12900 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-05-07 02:37:13.286 INFO 12900 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'webRequestLoggingFilter' to: [/*]
2018-05-07 02:37:13.286 INFO 12900 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'applicationContextIdFilter' to: [/*]
2018-05-07 02:37:14.587 INFO 12900 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@5fe94a96: startup date [Mon May 07 02:37:05 CST 2018]; root of context hierarchy
2018-05-07 02:37:14.775 INFO 12900 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-05-07 02:37:14.777 INFO 12900 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-05-07 02:37:14.946 INFO 12900 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-07 02:37:14.946 INFO 12900 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-07 02:37:15.038 INFO 12900 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-05-07 02:37:15.883 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/sofaboot/versions || /sofaboot/versions.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:15.889 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/beans || /beans.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:15.894 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)
2018-05-07 02:37:15.894 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/metrics || /metrics.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:15.896 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}" onto public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException
2018-05-07 02:37:15.899 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/health/readiness || /health/readiness.json],produces=[application/json]}" onto public java.lang.Object com.alipay.sofa.healthcheck.service.SofaBootReadinessCheckMvcEndpoint.invoke(java.security.Principal)
2018-05-07 02:37:15.901 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:15.905 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/configprops || /configprops.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:15.907 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/mappings || /mappings.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:15.914 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/dump || /dump.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:15.922 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/logfile || /logfile.json],methods=[GET || HEAD]}" onto public void org.springframework.boot.actuate.endpoint.mvc.LogFileMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws javax.servlet.ServletException,java.io.IOException
2018-05-07 02:37:15.929 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env/{name:.*}],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)
2018-05-07 02:37:15.929 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/env || /env.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:15.931 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/info || /info.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:15.932 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/health || /health.json],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(java.security.Principal)
2018-05-07 02:37:15.934 INFO 12900 --- [ main] o.s.b.a.e.mvc.EndpointHandlerMapping : Mapped "{[/trace || /trace.json],methods=[GET],produces=[application/json]}" onto public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()
2018-05-07 02:37:16.272 INFO 12900 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-05-07 02:37:16.296 INFO 12900 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 0
2018-05-07 02:37:17.522 INFO 12900 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8081 (http)
2018-05-07 02:37:17.536 INFO 12900 --- [ main] c.a.s.r.s.d.ClientConsumerApplication : Started ClientConsumerApplication in 19.234 seconds (JVM running for 21.96)
sync

以上成功运行完成一次服务发布和服务应用。

使用总结

SOFARPC是一款基于 Java 实现轻量级的RPC服务框架,基于Netty网络通信框架提供应用之间的点对点服务调用功能,SOFARPC 为应用之间提供远程服务调用能力,具备高可伸缩性、高容错性等特性,提供负载均衡,流量转发,链路追踪,链路数据透传,故障剔除等功能,支持 bolt,rest,dubbo 协议进行通信,其中 bolt 是蚂蚁金融服务集团开放的基于 Netty 开发的网络通信框架。搭建源码调试环境指定默认走本地文件注册中心,关于搭建集成Zookeeper注册中心环境参考https://www.jianshu.com/p/97323e1057e3。接下来重点源码解析SOFARPC各个模块源码。

文章目录