当前位置:网站首页>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.javaThe 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 !
边栏推荐
- Masa framework - DDD design (1)
- Configure ARP table entry restrictions and port security based on the interface (restrict users' private access to fool switches or illegal host access)
- Global and Chinese market of discharge machines 2022-2028: Research Report on technology, participants, trends, market size and share
- IP address translation address segment
- 二、mock平台的扩展
- Global and Chinese market of switching valves 2022-2028: Research Report on technology, participants, trends, market size and share
- john爆破出现Using default input encoding: UTF-8 Loaded 1 password hash (bcrypt [Blowfish 32/64 X3])
- 深度学习图像数据自动标注[通俗易懂]
- System Verilog实现优先级仲裁器
- 什么是泛型?- 泛型入门篇
猜你喜欢

伟立控股港交所上市:市值5亿港元 为湖北贡献一个IPO
![[leetcode] 14. Préfixe public le plus long](/img/70/e5be1a7c2e10776a040bfc8d7711a0.png)
[leetcode] 14. Préfixe public le plus long

几行代码搞定RPC服务注册和发现

上传代码到远程仓库报错error: remote origin already exists.

Changwan group rushed to Hong Kong stocks: the annual revenue was 289million, and Liu Hui had 53.46% voting rights

Use of openpose

Lampe respiratoire PWM

TCP server communication process (important)

大厂面试总结大全
![[essay solicitation activity] Dear developer, RT thread community calls you to contribute](/img/31/11409606718e0f4837f4cc572172a3.png)
[essay solicitation activity] Dear developer, RT thread community calls you to contribute
随机推荐
[error record] error -32000 received from application: there are no running service protocol
基于多元时间序列对高考预测分析案例
Privacy computing technology innovation and industry practice seminar: Learning
The computer comes with software to make the background color of the picture transparent (matting white background)
System Verilog implements priority arbiter
L'explosion de John utilise l'encodage d'entrée par défaut: UTF - 8 Loaded 1 password Hash (bcrypt [blowfish 32 / 64 X3])
[fluent] dart data type list set type (define set | initialize | generic usage | add elements after initialization | set generation function | set traversal)
Digital IC hand tearing code -- voting device
jsp 和 servlet 有什么区别?
Just a coincidence? The mysterious technology of apple ios16 is even consistent with the products of Chinese enterprises five years ago!
【Leetcode】14. Longest Common Prefix
&lt;四&gt; H264解码输出yuv文件
对接保时捷及3PL EDI案例
Seven charts, learn to do valuable business analysis
Global and Chinese markets for disposable insulin pumps 2022-2028: Research Report on technology, participants, trends, market size and share
Usage of sprintf() function in C language
P6774 [noi2020] tears in the era (block)
AP and F107 data sources and processing
大廠面試總結大全
LeetCode 5. Longest Palindromic Substring