分布式架构基础(三)手写简易版RPC

手写简易版RPC

RPC框架设计图

在这里插入图片描述

常用的RPC框架

  • WebService
  • Dubbo
  • Thrift
  • Grpc

Socket 实现RPC通信

使用socket实现RPC通信的核心:暴露服务、建立连接,序列化与反序列化,动态代理

服务端:

/**
* API 接口
**/
public instance IOrderService {

	String queryOrderList();

	String queryOrderById(String id);
}

/**
*API RpcRequest
**/
public class Rpcquest implements Serializable{

	private String className;

	private String methodName;

	private Object[] types;

	private Object[] args;
}


/**
* provide 接口实现类
**/
public class OrderService implements IOrderService {
	
	@Override
	public String queryOrderList() {
		return "QUERT ORDER LIST";
	}

	@Override
	public String queryOrderById(String id) {
		return "QUERY ORDER BY ID";
	}
}

/**
* provide 启动类
**/
public static void BootStart{
	
	// 实例化接口
	IOrderService orderService = new IOrderService();
	
	//实例化代理
	RpcProxyService rpcProxyService = new RpcProxyService();
	rpcProxyService.publisher(orderService, 8080);
}

/**
* provide 动态代理类
**/
public class RpcProxyService {
	
	private ExecutorService executorService = Executors.newCachedThread(20);

	public void publisher(Object service, int port) {
		//建立连接
		SocketService socketService = new SocketService(port);
		while (true) {
			Socket socket = socketServce.accept();
			executorService.execute(new ProcessorHandler(socket, service));
		}
	}


}

/**
* provide 线程类
* 在线程中处理监听
**/
public class ProcesserHandler implements Runnable {
	
	private Socket socket;

	private Object service;

	public ProcesserHandler (Socket socket, Object service) {
		this.socket = socket;
		this.service = service;
    }

	@Override
	public Object run(){
		
		//接收信息
		ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
		RpcRequest request = (RpcRequest) inputStream.readObject();

		Object obj = invoke(request);
		ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
		outputStream .writeObject(obj);
		outputStream.flush();
	}

	public Object invoke(RpcRequest request) {
		
		Class clazz = Class.forName(request.getClassName());
		Method method = clazz.getMethod(request.getMethodName(), request.getTypes());
		return mehtod.invoke(service, requeset.getArgs());
	}
}
客户端:

/**
* 启动类
**/

public class app {
	
	public static void main (String[] args) {
		
		//远程调用IOrdeService接口,
		IOrderService orderService = null;
		
		//通过代理类加载
		RpcProxyClient rpcProxyClient = new RpcProxyClient();
		orderService  = rpcProxyClient.clientProxy(IOrderService.class, "localhost", 8080);
		
		//调用接口
		sout(orderService.queryOrderList());
	}
}

/**
* 代理类
**/

public class RpcProxyClient {
	public <T> T clientProxy(final Class<?> instanceCls, final String host, final int port) {
		return Proxy.newProxyInstance(instanceCls.getClassLoader(), new Class<?> {instanceCls}, new RemoteInvocationHandler(host, port));
	}
}

/**
* InvocationHandler
**/
public class RemoteInvocationHandler implements InvocationHandler{
	
	private String host;
	private int port;

	public RemoteInvocationHandler (String host, int port) {
		this.host = host;
		this.port = port;
	} 

	@Override
	public Object invoke (Object proxy, Method method, Object[] args) {
		
		//封装成通信协议
		RpcNetTransport  rpcNetTransport = new RpcNetTransport(host, port);
		RpcRequest request = new RpcRequest();
		request .setClassName(method.getDeclaringClass.getName());
		request.setMethodName(method.getName());
		request.setTypes(method.getParamTypes());
		requeust.setArgs(args);
		return rpcNetTransport.send(request);
	}
}


/**
* 通信协议
**/
public class RpcNetTransport {
	
	private String host;
	private int port;

	public RpcNetTransport (String host, int port) {
		this.host = host;
		this.port = port;
	} 

	public Object send (RpcRequest request) {
	
		Socket socket = new Socket(host, port);
		ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
		outputStream.writerObject(request);
		outputStream.flush();

		ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
		return inputStream.readObject();
	}
}

注解版RPC

注解版RPC中需要注意两个spring的类:

  • BeanPostProcessor
  • ContextRefreshedEvent

其中涉及到一个模式:Mediator(中介者模式)

BeanPostProcessor

BeanPostProcessor也称为Bean后置处理器,它是Spring中定义的接口,在Spring容器的创建过程中(具体为Bean初始化前后)会回调BeanPostProcessor中定义的两个方法。BeanPostProcessor的源码如下:

public interface BeanPostProcessor {

    Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;

    Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;

}

其中postProcessBeforeInitialization方法会在每一个bean对象的初始化方法调用之前回调;postProcessAfterInitialization方法会在每个bean对象的初始化方法调用之后被回调。

BeanPostProcessor的执行是定义在容器的刷新过程中,容器刷新对象具体的方法为:AbstractApplicationContext.refresh()。在refresh方法执行的调用栈中会去调用AbstractAutowireCapableBeanFactory.doCreateBean()方法。

Demo

服务端
/**
* 注解类,所有有该注解的自动进行加载
**/

@Target(ElementType.TYPT)
@Retention(RetentionPolicy.RUNTIME)
@Component	
public @instance GpRemoteService {
}

/**
* 实现类
**/
@GpRemoteService
public class OrderService implements IOrderService {
	
	@Override
	public String queryOrderList() {
		return "QUERT ORDER LIST";
	}

	@Override
	public String queryOrderById(String id) {
		return "QUERY ORDER BY ID";
	}
}

/**
* 启动类,Spring的启动
**/
@Configuration
@ComponentScan("com.**.**")
public class BootStart{
	ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BootStart.class);
}


/**
* spring 容器加载完成后,执行BeanPostProcessor的实现类,将带有注解的类加载到容器中
**/
@Component
public class InitialMerdiator implements BeanPostProcessor {
	
	@Overrride
	public Object postProcessorAfterInitialization(Object bean, String beanName) throws BeansException {
		
		if(bean.getClass().isAnnotationPresent(GpRemoteService.class)) {
			
			Method[] methods = bean.getClass().getDeclaredMethods();
			
			for(Method method: methods) {
				String key = bean.getClass().getInterfaces()[0].getName() + "." + method.getName();
				 BeanMethodd beanMethod = new BeanMethod();
                beanMethod.setBean(bean);
                beanMethod.setMethod(method);

				Merdiator.map.put(key, method);
			}
		}
		return bean;
	}
}

/**
* beanMethod
**/
public class BeanMethod {
	private Object bean;
	private Method method;
	……
}


/**
* Merdiator
**/

public class Merdiator{

public static Map<String ,BeanMethod> map=new ConcurrentHashMap<>();

private Merdiator instance;

private Merdiator(){}

public static Merdiator getInstance(){
	if (instance == null) {
		synchronized(Merdiator.class) {
			if (instance == null) {
				instance = new Merdiator();
			} 
		} 
	}
}

 //根据request查询出需要的接口
 public Object processor(RpcRequest request) {
        
        String key = request.getClassName() + "." + request.getMethodName();
        BeanMethod beanMethod = map.get(key);
        if (beanMethod == null) {
            return null;
        }
        
        Object bean = beanMethod.getBean();
        Method method = beanMethod.getMethod();
        
        return method.invoke(bean, request.getArgs());
        
    }

}

/**
* spring 容器启动完成之后,会发布一个ContextRefreshedEvent。因此socket服务端监听发生在该事件中
**/
@Component
public class SocketServiceInitial implements ApplicationListener<ContextRefreshedEvent> {
    
    private finish ExecutorService executorService = Executors.newCachedThread();
    
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshendEvent) {
        SocketService socketService = null;
        
        try{
            socketService = new SocketService(8080);
            while(true) {
                Socket socket = socketService.accpect();
                executorService.execute(new ProcessorHandler(socket));
            }
        }
    }
}

public class ProcessorHandler implements Runnable {
    
    private Socket socket;
    
    public ProcessorHandler(Socket socket) {
        this.socket = socket;
    }
    
    @Override
    private void run(){
        ObjectInputStream inputStream = null;
        ObjectOutputStream outputStream = null;
        
        try {
            inputStream = new ObjectInputStream(socket.getInputStream());
            RpcRequest request = (RpcRequest)inputStream.readObject();
            
            //路由
            Mediator mediator = Mediator.getInstance();
            
            Object rs = mediator.processor(request);
            
            //将查询到的接口传到消费端
            outputStream = new ObjectOutputStream(socket.getOutpustStream());
            outputStream.writeObject(rs);
            outputStream.flush();
            
        }
    }
}
消费端
@Target(ElementType.FILED)
@Retention(RetentionPolicy.RUNTIME)
@Comonent
publci @interface GpReference{
    
}

@SpringbootApplication
public class UserServiceMain (
	
    public static void main (String[] args) {
        SpringApplication.run(UserServiceMain.class);
    }
)

/**
*	加载时机:初始化之前
* 	在初始化之前,需要将动态代理类加载到IOC容器中
**/
@Component
public class ReferenceInvokeProxy implements BeanPostProcessor {
    
    @Autowried
    private RemoteInvocationHandler invocationHandler;
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Filed[] fileds = bean.getClass().getDeclaredFileds();
        for(Filed filed: fileds) {
            if(filed.isAnnotationPresent(GpReference.class)) {
                filed.setAccessible(true);
                
                //针对GpReference注解进行代理
                Object proxy = Proxy.newProxyInstance(filed.getType().getClassLoad(), new Class<?>[]{filed.getType()}, invocationHandler);
                
                //相当于针对加了GpReference的注解,设置了一个代理,这个代理的实现是inovcationHandler
                field.set(bean,proxy);
            }
        }
        return bean;
       
    }
    
}

@Component
public class RemoteInvocationHandler implements InvocationHandler {
    
    @Value("${Gp.host}")
    private String host;
    @Value("${GP.port}")
    private int port;
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) {
        
        //建立连接
         RpcNetTransport rpcNetTransport=new RpcNetTransport(host,port);
        
        //传递数据
        RpcRequest request = new RpcRequest();
        request.setClassName(method.getDeclaringClass().getName());
        request.setMethodName(method.getName());
        request.setTypes(method.getParamterTypes());
        request.setArgs(args);
        
        return rpcNetTransport.send(request)
    }
}


@RestController
public class TestController{
    
    @GpReference
    private IOrderService orderService;
    
    @GetMapping("/test")
    public String queryOrderList(){
        return orderService.queryOrderList();
    }
}

猜你喜欢

转载自blog.csdn.net/baidu_41934937/article/details/114588379