本文章为学习后的总结,如果有错误,请各位及时帮我指正,感谢。
RPC 远程过程调用,是两个进程之间的调用。用于微服务之间通信。
在单体架构的时候,我们的Controller和Service 在同一个主机部署,当我要使用Service的时候我直接new 一个Service的实例,然后用 实例调用内部的方法,但是如果把Service抽取成微服务,则这些服务会跟Controller层部署在不同的主机上。这就导致我们原来直接new 实例不能这么做了。因为找不到Service的实现了。通过RPC可以间接帮你完成这件事情。这就是RPC的作用。
根据理解画个图,方便理解和复习。
如果没有RPC框架的话 我们要与其他服务器的进程进行通信需要自己使用socket通信
RPC框架其实就是把底层socket通信的机制给封装起来了,我们不用关心具体的实现。
从上图可以看到 我们只关心红色方框中的实现就可以了。并不需要关系我们调用的时候发生了什么。
Hadoop的RPC使用
1. 首先你要有三个类 调用服务的类 Controller 层, 提供服务的接口Service,服务的具体实现类ServiceImpl
2. 通过RPC启动服务的实现类作为一个等待调用的进程。
3. 通过RPC启动调用类,作为一个调用服务的进程。
调用Service的controller层
package com.hadoop.rpc;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import java.io.IOException;
import java.net.InetSocketAddress;
public class LoginController {
public static void main(String[] args) throws IOException {
new LoginController().login("rpcLogin", "快让我登录");
}
public boolean login(String u, String p) throws IOException {
LoginService proxy = RPC.getProxy(LoginService.class,
1L,
new InetSocketAddress("127.0.0.1", 5225),
new Configuration());
String login = proxy.login(u, p);
System.out.println(login);
return true;
}
}
提供服务的接口
package com.hadoop.rpc;
public interface LoginService {
public static final long versionID = 1L;
String login(String u, String p);
}
提供服务的具体实现
package com.hadoop.rpc;
public class LoginServiceImpl implements LoginService {
public String login(String u, String p) {
return u + " " + p + " login successfully!";
}
}
启动进程的客户端
package com.hadoop.rpc;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.ipc.RPC;
import java.io.IOException;
public class ServiceClient {
public static void main(String[] args) throws IOException {
RPC.Builder builder = new RPC.Builder(new Configuration());
RPC.Server server = builder.setBindAddress("127.0.0.1")
.setPort(5225)
.setProtocol(LoginService.class)
.setInstance(new LoginServiceImpl()).build();
server.start();
}
}
运行结果
服务端等待被调用
调用端调用后的结果
对于刚开是学,我产生一个疑问,在一个项目中运行不就可以了么,为什么还要把调用端和服务端分开部署呢?
这么麻烦能带来什么好处呢?
通过调用的过程,来体会一下好处
1. 我们不用关心使用的网络协议和网络和IO模型
2. 我们知道传递的参数具体是什么样的
3. 跨语言,我的调用端可以使用任何语言给我提供服务,我不需要知道它使用的是什么实现的。
为什么使用RPC把Service分离
1. 当用户量不大,业务逻辑简单的时候确实没必要这么做。
2. 当系统的访问量增大的时候,我们一台服务器无法承受,我们就可以把业务实现分成几个服务器部署。
3. 当我们有众多系统的时候,我们的服务是可以通用的,如果不是分离的话可能你要在每个系统都实现一下相同的业务逻辑。如果业务变动,带来的维护成本大大增加。你要在各个系统都更新一下代码。