Java-互联网系统架构设计与实践-2

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);

    }
}

运行结果

RPCServer.java
RPCClient.java

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();
    }
}

运行结果

RMIServerTest

RMIClientTest

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值