Java-2-互联网系统架构设计与实践
目录
1. RPCServer与RPCClient连接通信使用Socket和线程池
RPCServer项目中的代码
- HelloService.java
package org.example;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* 定义服务端服务的接口
*/
public interface HelloService extends Remote {
String sayHello(String name)throws RemoteException;
}
- HelloServiceImpl.java
package org.example;
import java.rmi.RemoteException;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.UnicastRemoteObject;
/**
* 服务端服务的实现类
*/
public class HelloServiceImpll extends UnicastRemoteObject implements HelloService{
protected HelloServiceImpll() throws RemoteException {
}
protected HelloServiceImpll(int port) throws RemoteException {
super(port);
}
protected HelloServiceImpll(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf) throws RemoteException {
super(port, csf, ssf);
}
@Override
public String sayHello(String name) throws RemoteException{
return "say hello to " +name;
}
}
- RegisterCenter.java
package org.example;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 服务的注册仲尼,用来管理各种服务,存储服务,获取服务,调用服务
* 如果有客户端调用服务,到注册中心来获取服务
* 注册中心提供一个Map集合来存户和管理服务
* 建:是服务的全称,全限定名
* 值:是服务的对象,实现类的对象
*/
public class RegisterCenter {
// 创建一个map集合,用于存储服务
private Map<String, Object> serviceRegister = new HashMap<>();
// 创建线程池,线程池中线程的数量,根据处理器的数量确定
private ExecutorService executorService = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors()
);
// 注册中心运行的标志
private boolean isRunning = false; // 默认没有运行
// 启动注册中心
public void start() throws IOException {
// 创建服务端的socket
ServerSocket serverSocket = new ServerSocket(9999);
System.out.println("服务启动");
isRunning = true;
while (isRunning) {
Socket socket = serverSocket.accept();
// Thread t = new Thread(new ServiceTask(socket));
// t.start();
executorService.execute(new ServiceTask(socket));
}
}
// 关闭注册中心
public void stop() {
// 将运行的标志改为false
isRunning = false;
executorService.shutdown();
}
// 向注册中心注册服务
// 第一个参数是服务结构的类型,第二个参数是服务接口的实现类的类型
public void registerService(Class serviceClass, Class serviceImplClass) throws InstantiationException, IllegalAccessException {
serviceRegister.put(serviceClass.getName(), serviceImplClass.newInstance())
;
}
private class ServiceTask implements Runnable {
private Socket socket;
public ServiceTask(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
// 获取输入流
try {
ois = new ObjectInputStream(socket.getInputStream());
// 读取服务的名称
String serviceName = ois.readUTF();
// 读取方法的名称
String methodName = ois.readUTF();
// 方法的参数类型
Class[] parameterTypes = (Class[]) ois.readObject();
// 读取方法的参数
Object[] args = (Object[]) ois.readObject();
// 先获取service
HelloService helloService = (HelloService) serviceRegister.get(serviceName);
// 获取方法
Method method = helloService.getClass().getMethod(methodName, parameterTypes);
// 调用方法
Object result = method.invoke(helloService, args);
// 将结果返回给客户端
oos = new ObjectOutputStream(socket.getOutputStream());
System.out.println(result);
// 写结果
oos.writeObject(result);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} finally {
try {
if (oos != null) {
oos.close();
}
if(ois != null){
ois.close();
}
if(socket != null){
socket.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
- RegisterCenterTest.java
package org.example;
import java.io.IOException;
public class RegisterCenterTest {
public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException {
// 创建注册中心
RegisterCenter registerCenter = new RegisterCenter();
// 将服务注册到注册中心
registerCenter.registerService(HelloService.class, HelloServiceImpll.class);
// 启动注册中心
registerCenter.start();
}
}
RPCClient项目中的代码
- HelloService.java
package org.example;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* 服务端服务
*/
public interface HelloService extends Remote {
String sayHello(String name) throws RemoteException;
}
- Client.java
package org.example;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.Socket;
public class Client {
public static Object getProxyObject(){
return Proxy.newProxyInstance(HelloService.class.getClassLoader(),
new Class[]{HelloService.class},
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 连接服务器
Socket socket = new Socket("127.0.0.1",9999);
// 获取输出流
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
// 写服务的名字
oos.writeUTF(HelloService.class.getName());
oos.writeUTF(method.getName());
// 写方法的名字
oos.writeObject(method.getParameterTypes());
// 写方法的参数
oos.writeObject(args);
// 等待服务器返回结果,创建输入流
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
Object result = ois.readObject();
return result
;
}
});
}
}
- ClientTest.java
package org.example;
import java.rmi.RemoteException;
public class ClientTest {
public static void main(String[] args) throws RemoteException {
System.out.println(Client.getProxyObject());
// 获取动态处理对象
HelloService helloService = (HelloService) Client.getProxyObject();
System.out.println(helloService);
// 调用动态代理对象的方法
String retStr = (String) helloService.sayHello("rose");
System.out.println(retStr);
}
}
运行结果
2.RMI通信
RPCServer项目中
- RMIServer.java
package org.example;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RMIServer {
public void server() throws RemoteException , AlreadyBoundException, MalformedURLException{
// 创建一个服务对象
HelloServiceImpll helloService = new HelloServiceImpll();
// 创建注册中心实例,给定端口号
Registry registry = LocateRegistry.createRegistry(9999);
// 将服务绑定到注册中心
Naming.bind("rmi://localhost:9999/hello",helloService)
;
// 绑定成功
System.out.println("绑定成功");
}
}
- RMIServerTest.java
package org.example;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
public class RMIServerTest {
public static void main(String[] args) throws MalformedURLException, AlreadyBoundException, RemoteException {
// 创建Server 对象
RMIServer rmiServer = new RMIServer();
rmiServer.server();
}
}
RPCClient项目中
- RMIClient.java
package org.example;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class RMIClient {
public void client() throws RemoteException, RemoteException, MalformedURLException, NotBoundException {
// 获取服务的动态代理对象
HelloService helloService = (HelloService) Naming.lookup("rmi://localhost:9999/hello");
String retStr = helloService.sayHello("rose");
System.out.println(retStr);
}
}
- RMIClientTest.java
package org.example;
import java.net.MalformedURLException;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class RMIClientTest {
public static void main(String[] args) throws MalformedURLException, NotBoundException, RemoteException {
// 创建客户端对象
RMIClient rmiClient = new RMIClient();
rmiClient.client();
}
}