当前位置:网站首页>A few lines of code to complete RPC service registration and discovery
A few lines of code to complete RPC service registration and discovery
2022-07-02 17:07:00 【Java confidant_】
Before coding , I need to tell you , The whole project is implemented according to the superposition of one function module , Because the article layout is not suitable for putting large blocks of code , In this article, I will intercept the most critical code and explain it to you , To get the complete code , You can go to Github Upload and download , It has been officially open source .
easy-rpc Open source address :
https://github.com/CoderLeixiaoshuai/easy-rpcBe careful : The source code may be updated , Remember to pull the latest .
Demand analysis : Service registration and discovery
rpc The first function module of the project is : Service registration and discovery
, This function is also the core and key of the whole framework .
our rpc Projects are not used to build environments , Make a wheel , You only need to realize the most basic functions :
The service instance registers its metadata to the registry , Metadata includes : example ip、 port 、 Interface description, etc ;
If the client instance wants to call the server interface, it will first connect to the registry , Find out The server instance to be called ;
Get multiple server instances , The client will select a suitable instance according to the load balancing algorithm RPC call .
The need is clear , Let's start with the code .
Introduce tripartite dependence
There are still many reliable registration centers on the market , This time, we plan to be compatible with both registries :Zookeeper and Nacos, Isn't it conscience ?! Before using, you need to introduce the following dependencies .
And Zookeeper Interaction can introduce corresponding SDK,zkclient It's a good choice ;JSON Serialization and deserialization can introduce fastjson, Although there are often loopholes , But China still has to support :
<!-- Zookeeper client -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<!--Json Serialize the de sequence -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.80</version>
</dependency>
as for Nacos, You can directly introduce official SDK:nacos-client:
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.0.3</version>
</dependency>
The server realizes service registration
Service registration and discovery are divided into two functions : Server registration and client discovery , Let's first implement the server registration function .
Define the service registration interface
In the process of daily work or learning coding , We must get used to interface oriented programming , Doing so will help enhance code scalability .
According to the previous requirement description , Service registration only needs to do one thing : Service registration , We can define an interface :ServiceRegistry
, Define a method in the interface :register
, The code is as follows :
public interface ServiceRegistry {
/**
* Registration service information
*
* @param serviceInfo Services to be registered
* @throws Exception abnormal
*/
void register(ServiceInfo serviceInfo) throws Exception;
}
Services register with the registry , The registered content defines a class ServiceInfo
To encapsulate .
/**
* The service name
*/
private String serviceName;
/**
* ip Address
*/
private String ip;
/**
* Port number
*/
private Integer port;
/**
* class object
*
*/
private Class<?> clazz;
/**
* bean object
*/
private Object obj;
// Omit get set Method ……
}
Zookeeper Implement service registration
We try to use Zookeeper To realize the service registration function , First create a new class to implement the previously defined service registration interface :
public class ZookeeperServiceRegistry implements ServiceRegistry {
}
Next, rewrite register
Method , The main functions include calling Zookeeper Interface to create service nodes and instance nodes . The service node is a permanent node , Only create once ; The instance node is a temporary node , If the instance fails, it goes offline , The instance node will be deleted automatically .
// ZookeeperServiceRegistry.java
@Override
public void register(ServiceInfo serviceInfo) throws Exception {
logger.info("Registering service: {}", serviceInfo);
// establish ZK Permanent nodes ( Service node )
String servicePath = "/com/leixiaoshuai/easyrpc/" + serviceInfo.getServiceName() + "/service";
if (!zkClient.exists(servicePath)) {
zkClient.createPersistent(servicePath, true);
}
// establish ZK Temporary node ( Instance node )
String uri = JSON.toJSONString(serviceInfo);
uri = URLEncoder.encode(uri, "UTF-8");
String uriPath = servicePath + "/" + uri;
if (zkClient.exists(uriPath)) {
zkClient.delete(uriPath);
}
zkClient.createEphemeral(uriPath);
}
The code is very simple , You can understand it by reading the notes .
Nacos Implement service registration
Besides using Zookeeper To achieve , We can also use Nacos, Like the above, let's build a class first :
public class NacosServiceRegistry implements ServiceRegistry {
}
Then write the construction method ,NacosServiceRegistry After the class is instantiated Nacos The client should also be connected Nacos Server side .
// NacosServiceRegistry.java
public NacosServiceRegistry(String serverList) throws NacosException {
// Use factory classes to create registry objects , Structure parameter is Nacos Server Of ip Address , Connect Nacos The server
naming = NamingFactory.createNamingService(serverList);
// Print Nacos Server Operating state
logger.info("Nacos server status: {}", naming.getServerStatus());
}
get NamingService After the instance object of class , You can call the instance registration interface to complete the service registration .
// NacosServiceRegistry.java
@Override
public void register(ServiceInfo serviceInfo) throws Exception {
// Register the current service instance
naming.registerInstance(serviceInfo.getServiceName(), buildInstance(serviceInfo));
}
private Instance buildInstance(ServiceInfo serviceInfo) {
// Register the instance information to Nacos center
Instance instance = new Instance();
instance.setIp(serviceInfo.getIp());
instance.setPort(serviceInfo.getPort());
// TODO add more metadata
return instance;
}
Be careful :NamingService Class provides many useful methods , You can try it yourself .
The client implements service discovery
Define the service discovery interface
The service instance has been registered to Zookeeper perhaps Nacos Server side , Now, if the client wants to call the server, it must first get the list of server instances , This process is actually Service discovery .
Let's first define an abstract interface , The main function of this interface is to define an interface for obtaining service instances :
public interface ServiceDiscovery {
/**
* Randomly select a healthy instance by service name
* @param serviceName The service name
* @return Instance object
*/
InstanceInfo selectOneInstance(String serviceName);
}
Randomly select an instance to simulate load balancing , Try to distribute requests evenly among instances .
Zookeeper Implementing service discovery
Use... In the front Zookeeper Realize the service registration function , Here we use it again Zookeeper To realize the service discovery function , First define a class implementation ServiceDiscovery Interface :
public class ZookeeperServiceDiscovery implements ServiceDiscovery {
}
The following is the implementation of the core method :selectOneInstance
Zookeeper Inside is a tree node , The list of service instances can be obtained by finding all child nodes of a specified node . How to select an instance after getting the list of service instances ? Here we can introduce the load balancing algorithm .
// ZookeeperServiceDiscovery.java
@Override
public InstanceInfo selectOneInstance(String serviceName) {
String servicePath = "/com/leixiaoshuai/easyrpc/" + serviceName + "/service";
final List<String> childrenNodes = zkClient.getChildren(servicePath);
return Optional.ofNullable(childrenNodes)
.orElse(new ArrayList<>())
.stream()
.map(node -> {
try {
// Pass the service information through URL After decoding, it is deserialized into an object
String serviceInstanceJson = URLDecoder.decode(node, "UTF-8");
return JSON.parseObject(serviceInstanceJson, InstanceInfo.class);
} catch (UnsupportedEncodingException e) {
logger.error("Fail to decode", e);
}
return null;
}).filter(Objects::nonNull).findAny().get();
}
Be careful : The current project is only for learning , Complex load balancing algorithms are not introduced here , Interested students can add by themselves , Welcome to submit MR Contribution code .
Nacos Implementing service discovery
Finally came Nacos The implementation of the , Don't say much. First define a class :
public class NacosServiceDiscovery implements ServiceDiscovery {
}
We also need to implement the core method :selectOneInstance
.Nacos The implementation of is relatively simple , because Nacos Official SDK It's so powerful , We can call the corresponding interface directly ,Nacos According to the algorithm, a healthy instance will be randomly selected , We don't have to pay attention to details .
// ZookeeperServiceDiscovery.java
@Override
public InstanceInfo selectOneInstance(String serviceName) {
Instance instance;
try {
// call nacos Provided interface , Pick a service instance randomly , Algorithm dependence of load balancing nacos The implementation of the
instance = namingService.selectOneHealthyInstance(serviceName);
} catch (NacosException e) {
logger.error("Nacos exception", e);
return null;
}
// Encapsulate the instance object and return
InstanceInfo instanceInfo = new InstanceInfo();
instanceInfo.setServiceName(instance.getServiceName());
instanceInfo.setIp(instance.getIp());
instanceInfo.setPort(instance.getPort());
return instanceInfo;
}
The source code listing
The list of source codes used for service registration and discovery is as follows :
├── easy-rpc-example
├── easy-rpc-spring-boot-starter
│ ├── pom.xml
│ ├── src
│ │ └── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── leixiaoshuai
│ │ │ └── easyrpc
│ │ │ ├── client
│ │ │ │ ├── ClientProxyFactory.java
│ │ │ │ ├── discovery
│ │ │ │ │ ├── NacosServiceDiscovery.java
│ │ │ │ │ ├── ServiceDiscovery.java
│ │ │ │ │ └── ZookeeperServiceDiscovery.java
│ │ │ ├── common
│ │ │ │ └── InstanceInfo.java
│ │ │ └── server
│ │ │ └── registry
│ │ │ ├── NacosServiceRegistry.java
│ │ │ ├── ServiceRegistry.java
│ │ │ └── ZookeeperServiceRegistry.java
The complete source code can go by itself Github Pick up :
https://github.com/CoderLeixiaoshuai/easy-rpc
Summary
This article implements RPC The framework implements the service registration and discovery function , I believe you have a comprehensive grasp of this process .
The premise of communication between client and server is to know each other's ip And port , Service registration is to register your meta information (ip、 Port, etc ) Register with the registry (Registry), In this way, the client can register from the registry (Registry) Get yourself " Interested in " Service instance of .
The service registration and discovery mechanism can be assisted by some middleware , Such as the more popular :Zookeeper perhaps Nacos etc. .
recommend
Technical involution group , Learn together !!
PS: Because the official account platform changed the push rules. , If you don't want to miss the content , Remember to click after reading “ Looking at ”, Add one “ Star standard ”, In this way, each new article push will appear in your subscription list for the first time . spot “ Looking at ” Support us !
边栏推荐
- [essay solicitation activity] Dear developer, RT thread community calls you to contribute
- Global and Chinese markets for slotting milling machines 2022-2028: Research Report on technology, participants, trends, market size and share
- PWM控制舵机
- 上传代码到远程仓库报错error: remote origin already exists.
- Classic quotations
- Learning Weekly - total issue 60 - 25th week of 2022
- Leetcode1380: lucky numbers in matrix
- [error record] the connection of the flutter device shows loading (disconnect | delete the shuttle/bin/cache/lockfile file)
- ThreadLocal
- 深度学习图像数据自动标注[通俗易懂]
猜你喜欢
Tech talk activity preview | building intelligent visual products based on Amazon kVs
綠竹生物沖刺港股:年期內虧損超5億 泰格醫藥與北京亦莊是股東
Cell:清华程功组揭示皮肤菌群的一种气味挥发物促进黄病毒感染宿主吸引蚊虫...
[leetcode] 14. Préfixe public le plus long
Configure ARP table entry restrictions and port security based on the interface (restrict users' private access to fool switches or illegal host access)
基于Impala的高性能数仓实践之执行引擎模块
A week of short video platform 30W exposure, small magic push helps physical businesses turn losses into profits
⌈ 2022 ⌋ how to use webp gracefully in projects
几行代码搞定RPC服务注册和发现
AP and F107 data sources and processing
随机推荐
DGraph: 大规模动态图数据集
The poor family once again gave birth to a noble son: Jiangxi poor county got the provincial number one, what did you do right?
Method of C language self defining function
DigiCert SSL证书支持中文域名申请吗?
What is the difference between JSP and servlet?
IP地址转换地址段
【云原生】简单谈谈海量数据采集组件Flume的理解
go-zero微服务实战系列(八、如何处理每秒上万次的下单请求)
Learning Weekly - total issue 60 - 25th week of 2022
Résumé de l'entrevue de Dachang Daquan
深度学习图像数据自动标注[通俗易懂]
Hard core! One configuration center for 8 classes!
绿竹生物冲刺港股:年期内亏损超5亿 泰格医药与北京亦庄是股东
VMware安装win10镜像
&lt; IV & gt; H264 decode output YUV file
OpenPose的使用
綠竹生物沖刺港股:年期內虧損超5億 泰格醫藥與北京亦莊是股東
Error when uploading code to remote warehouse: remote origin already exists
TCP server communication process (important)
The macrogenome microbiome knowledge you want is all here (2022.7)