提交 0ccffe60 编写于 作者: S shuang.kou

[v1.0]improve:use map to store service data

上级 9d03e5cf
......@@ -8,10 +8,10 @@
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="rpc-framework-core" />
<module name="hello-service-api" />
<module name="example-server" />
<module name="rpc-framework-simple" />
<module name="example-client" />
<module name="hello-service-api" />
<module name="rpc-framework-common" />
</profile>
</annotationProcessing>
......
......@@ -30,7 +30,7 @@
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date" />
<option name="myAdditionalJavadocTags" value="date,createTime" />
</inspection_tool>
</profile>
</component>
\ No newline at end of file
z
java:S2139&"XEither log this exception and handle it, or rethrow it with some contextual information.(ú×Þ³ùÿÿÿÿ8í½ðÁ .
Q
java:S3740"/Provide the parametrized type for this generic.(Õ‚±¡øÿÿÿÿ8öšãÁ .
g java:S112("FDefine and throw a dedicated exception instead of using a generic one.(Ò‚Òéüÿÿÿÿ8‰¦îÁ .
\ No newline at end of file
T
java:S1135)"2Complete the task associated to this TODO comment.(8.
f
java:S1128"IRemove this unused import 'github.javaguide.enumeration.RpcResponseCode'.(ޕ8.
Y
java:S1128"=Remove this unused import 'github.javaguide.dto.RpcResponse'.(8.
\ No newline at end of file
a
java:S1128"DRemove this unused import 'github.javaguide.exception.RpcException'.(8ܠ.
o
java:S1128"MRemove this unused import 'github.javaguide.enumeration.RpcErrorMessageEnum'.(Һ8ܠ.
\ No newline at end of file
j
java:S1128 "HRemove this unused import 'java.lang.reflect.InvocationTargetException'.(辆8ܠ.
f
java:S1128"IRemove this unused import 'github.javaguide.enumeration.RpcResponseCode'.(ޕ8ܠ.
W
java:S1128 "5Remove this unused import 'java.lang.reflect.Method'.(͓8ܠ.
\ No newline at end of file
T
java:S1135"2Complete the task associated to this TODO comment.(ö¤¦Âúÿÿÿÿ8ªöîÝ .
O
java:S11352"2Complete the task associated to this TODO comment.(É÷§‰8ªöîÝ .
›
java:S1130F"yRemove the declaration of thrown exception 'java.lang.ClassNotFoundException', as it cannot be thrown from method's body.(Íÿæ·üÿÿÿÿ8ÆúÝÞ .
\ No newline at end of file
......@@ -29,16 +29,12 @@ r
Brpc-framework-simple/src/main/java/github/javaguide/RpcClient.java,0/7/07643339d701578f80c084a95e22ac5651f4c58b
w
Grpc-framework-simple/src/main/java/github/javaguide/RpcClientProxy.java,6/4/64dea2f6fe697035b024637b900872293e816f7d
u
Erpc-framework-simple/src/main/java/github/javaguide/WorkerThread.java,2/1/21fca0301eb1bd531f6ad0f4077fb82662325ef3
r
Brpc-framework-simple/src/main/java/github/javaguide/RpcServer.java,0/8/086d7cc1989088b68798f225e07ca046fcfed5b2

Oexample-server/src/main/java/github/javaguide/RpcFrameworkSimpleServerMain.java,f/2/f27c58e20df8a3c709a42909516fe0201b357eaa

Oexample-client/src/main/java/github/javaguide/RpcFrameworkSimpleClientMain.java,5/e/5eb67949aee12c29202ad46a9a5acdd558cc76b9

Urpc-framework-common/src/main/java/github/javaguide/enumeration/ErrorMessageEnum.java,5/b/5bae0f0608ecec48b7a357686f8a10414a319fd8

Orpc-framework-common/src/main/java/github/javaguide/exception/RpcException.java,6/4/64c8f86fb65ec6e433ea6026803396c5250fbc79
x
......@@ -46,4 +42,12 @@ Hrpc-framework-common/src/main/java/github/javaguide/dto/RpcResponse.java,b/d/b
t
Dexample-server/src/main/java/github/javaguide/HelloServiceImpl2.java,c/d/cda3f378ef563e8d2ab13b9c22ab925f13f2fde6

Trpc-framework-common/src/main/java/github/javaguide/enumeration/RpcResponseCode.java,5/f/5f3d4a2735af7c561cf521c9e40f174434677620
\ No newline at end of file
Trpc-framework-common/src/main/java/github/javaguide/enumeration/RpcResponseCode.java,5/f/5f3d4a2735af7c561cf521c9e40f174434677620

Xrpc-framework-common/src/main/java/github/javaguide/enumeration/RpcErrorMessageEnum.java,8/3/83d611de4efdb638903513fb6af99646e707a994

Rrpc-framework-simple/src/main/java/github/javaguide/RpcRequestHandlerRunnable.java,a/5/a5cef486f97a5ac690fd68253ccb05a272eed822
x
Hrpc-framework-simple/src/main/java/github/javaguide/ServiceRegistry.java,d/0/d02ab7f8362272316c048349fbcee5439d04001e
z
Jrpc-framework-simple/src/main/java/github/javaguide/RpcRequestHandler.java,e/1/e1bb46d5a6fb0c76bfed0787c1fc324c20999044
\ No newline at end of file
package github.javaguide;
import github.javaguide.remoting.socket.RpcClientProxy;
/**
* @author shuang.kou
* @createTime 2020年05月10日 07:25:00
......
package github.javaguide;
import github.javaguide.registry.DefaultServiceRegistry;
import github.javaguide.remoting.socket.RpcServer;
/**
* @author shuang.kou
* @createTime 2020年05月10日 07:25:00
*/
public class RpcFrameworkSimpleServerMain {
public static void main(String[] args) {
RpcServer rpcServer = new RpcServer();
rpcServer.register(new HelloServiceImpl(), 9999);
// TODO 修改实现方式,通过map存放service解决只能注册一个service
System.out.println("后面的不会执行");
rpcServer.register(new HelloServiceImpl(), 9999);
HelloServiceImpl helloService = new HelloServiceImpl();
DefaultServiceRegistry defaultServiceRegistry = new DefaultServiceRegistry();
// 手动注册
defaultServiceRegistry.register(helloService);
RpcServer rpcServer = new RpcServer(defaultServiceRegistry);
rpcServer.start(9999);
}
}
......@@ -14,7 +14,8 @@ import lombok.ToString;
public enum RpcErrorMessageEnum {
SERVICE_INVOCATION_FAILURE("服务调用失败"),
SERVICE_CAN_NOT_BE_NULL("注册的服务不能为空");
SERVICE_CAN_NOT_BE_FOUND("没有找到指定的服务"),
SERVICE_NOT_IMPLEMENT_ANY_INTERFACE("注册的服务没有实现任何接口");
private final String message;
......
package github.javaguide.registry;
import github.javaguide.enumeration.RpcErrorMessageEnum;
import github.javaguide.exception.RpcException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author shuang.kou
* @createTime 2020年05月13日 11:23:00
*/
public class DefaultServiceRegistry implements ServiceRegistry {
private static final Logger logger = LoggerFactory.getLogger(DefaultServiceRegistry.class);
/**
* 接口名和服务的对应关系,TODO 处理一个接口被两个实现类实现的情况
* key:service/interface name
* value:service
*/
private final Map<String, Object> serviceMap = new ConcurrentHashMap<>();
private final Set<String> registeredService = ConcurrentHashMap.newKeySet();
/**
* TODO 修改为扫描注解注册
* 将这个对象所有实现的接口都注册进去
*/
@Override
public synchronized <T> void register(T service) {
String serviceName = service.getClass().getCanonicalName();
if (registeredService.contains(serviceName)) {
return;
}
registeredService.add(serviceName);
Class[] interfaces = service.getClass().getInterfaces();
if (interfaces.length == 0) {
throw new RpcException(RpcErrorMessageEnum.SERVICE_NOT_IMPLEMENT_ANY_INTERFACE);
}
for (Class i : interfaces) {
serviceMap.put(i.getCanonicalName(), service);
}
logger.info("Add service: {} and interfaces:{}", serviceName, service.getClass().getInterfaces());
}
@Override
public synchronized Object getService(String serviceName) {
Object service = serviceMap.get(serviceName);
if (null == service) {
throw new RpcException(RpcErrorMessageEnum.SERVICE_CAN_NOT_BE_FOUND);
}
return service;
}
}
package github.javaguide.registry;
/**
* @author shuang.kou
* @createTime 2020年05月13日 08:39:00
*/
public interface ServiceRegistry {
<T> void register(T service);
Object getService(String serviceName);
}
package github.javaguide.remoting;
import github.javaguide.dto.RpcRequest;
import github.javaguide.dto.RpcResponse;
import github.javaguide.enumeration.RpcResponseCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author shuang.kou
* @createTime 2020年05月13日 09:05:00
*/
public class RpcRequestHandler {
private static final Logger logger = LoggerFactory.getLogger(RpcRequestHandler.class);
public Object handle(RpcRequest rpcRequest, Object service) {
Object result = null;
try {
result = invokeTargetMethod(rpcRequest, service);
logger.info("service:{} successful invoke method:{}", rpcRequest.getInterfaceName(), rpcRequest.getMethodName());
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
logger.error("occur exception", e);
}
return result;
}
private Object invokeTargetMethod(RpcRequest rpcRequest, Object service) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
Method method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
if (null == method) {
return RpcResponse.fail(RpcResponseCode.NOT_FOUND_METHOD);
}
return method.invoke(service, rpcRequest.getParameters());
}
}
package github.javaguide;
package github.javaguide.remoting.socket;
import github.javaguide.dto.RpcRequest;
import github.javaguide.dto.RpcResponse;
......@@ -18,7 +18,7 @@ import java.net.Socket;
* @createTime 2020年05月10日 18:40:00
*/
public class RpcClient {
public static final Logger logger = LoggerFactory.getLogger(RpcClient.class);
private static final Logger logger = LoggerFactory.getLogger(RpcClient.class);
public Object sendRpcRequest(RpcRequest rpcRequest, String host, int port) {
try (Socket socket = new Socket(host, port)) {
......
package github.javaguide;
package github.javaguide.remoting.socket;
import github.javaguide.dto.RpcRequest;
import org.slf4j.Logger;
......
package github.javaguide;
package github.javaguide.remoting.socket;
import github.javaguide.dto.RpcRequest;
import github.javaguide.dto.RpcResponse;
import github.javaguide.enumeration.RpcResponseCode;
import github.javaguide.registry.ServiceRegistry;
import github.javaguide.remoting.RpcRequestHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.Socket;
/**
* @author shuang.kou
* @createTime 2020年05月10日 09:18:00
*/
public class ClientMessageHandlerThread implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(ClientMessageHandlerThread.class);
public class RpcRequestHandlerRunnable implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(RpcRequestHandlerRunnable.class);
private Socket socket;
private Object service;
private RpcRequestHandler rpcRequestHandler;
private ServiceRegistry serviceRegistry;
public ClientMessageHandlerThread(Socket socket, Object service) {
public RpcRequestHandlerRunnable(Socket socket, RpcRequestHandler rpcRequestHandler, ServiceRegistry serviceRegistry) {
this.socket = socket;
this.service = service;
this.rpcRequestHandler = rpcRequestHandler;
this.serviceRegistry = serviceRegistry;
}
@Override
public void run() {
// 注意使用 try-with-resources ,因为这样更加优雅
// 并且,try-with-resources 语句在编写必须关闭资源的代码时会更容易,也不会出错
try (ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream())) {
RpcRequest rpcRequest = (RpcRequest) objectInputStream.readObject();
Object result = invokeTargetMethod(rpcRequest);
String interfaceName = rpcRequest.getInterfaceName();
Object service = serviceRegistry.getService(interfaceName);
Object result = rpcRequestHandler.handle(rpcRequest, service);
objectOutputStream.writeObject(RpcResponse.success(result));
objectOutputStream.flush();
} catch (IOException | ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
} catch (IOException | ClassNotFoundException e) {
logger.error("occur exception:", e);
}
}
private Object invokeTargetMethod(RpcRequest rpcRequest) throws NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InvocationTargetException {
Class<?> cls = Class.forName(rpcRequest.getInterfaceName());
// 判断类是否实现了对应的接口
if (!cls.isAssignableFrom(service.getClass())) {
return RpcResponse.fail(RpcResponseCode.NOT_FOUND_CLASS);
}
Method method = service.getClass().getMethod(rpcRequest.getMethodName(), rpcRequest.getParamTypes());
if (null == method) {
return RpcResponse.fail(RpcResponseCode.NOT_FOUND_METHOD);
}
return method.invoke(service, rpcRequest.getParameters());
}
}
package github.javaguide;
package github.javaguide.remoting.socket;
import github.javaguide.enumeration.RpcErrorMessageEnum;
import github.javaguide.exception.RpcException;
import github.javaguide.remoting.RpcRequestHandler;
import github.javaguide.registry.ServiceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -21,35 +21,35 @@ import java.util.concurrent.TimeUnit;
* @createTime 2020年05月10日 08:01:00
*/
public class RpcServer {
/**
* 线程池参数
*/
private static final int CORE_POOL_SIZE = 10;
private static final int MAXIMUM_POOL_SIZE_SIZE = 100;
private static final int KEEP_ALIVE_TIME = 1;
private static final int BLOCKING_QUEUE_CAPACITY = 100;
private ExecutorService threadPool;
private RpcRequestHandler rpcRequestHandler = new RpcRequestHandler();
private static final Logger logger = LoggerFactory.getLogger(RpcServer.class);
private final ServiceRegistry serviceRegistry;
public RpcServer() {
// 线程池参数
int corePoolSize = 10;
int maximumPoolSizeSize = 100;
long keepAliveTime = 1;
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(100);
public RpcServer(ServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry;
BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(BLOCKING_QUEUE_CAPACITY);
ThreadFactory threadFactory = Executors.defaultThreadFactory();
this.threadPool = new ThreadPoolExecutor(corePoolSize, maximumPoolSizeSize, keepAliveTime, TimeUnit.MINUTES, workQueue, threadFactory);
this.threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE_SIZE, KEEP_ALIVE_TIME, TimeUnit.MINUTES, workQueue, threadFactory);
}
/**
* 服务端主动注册服务
* TODO 1.定义一个 hashmap 存放相关的service
* 2. 修改为扫描注解注册
*/
public void register(Object service, int port) {
if (null == service) {
throw new RpcException(RpcErrorMessageEnum.SERVICE_CAN_NOT_BE_NULL);
}
public void start(int port) {
try (ServerSocket server = new ServerSocket(port);) {
logger.info("server starts...");
Socket socket;
while ((socket = server.accept()) != null) {
logger.info("client connected");
threadPool.execute(new ClientMessageHandlerThread(socket, service));
threadPool.execute(new RpcRequestHandlerRunnable(socket, rpcRequestHandler, serviceRegistry));
}
threadPool.shutdown();
} catch (IOException e) {
logger.error("occur IOException:", e);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册