Java RMI : Rejecting requests when saturation is reached

标签 java rmi

我有一个 RMI 服务器,需要通过模拟多个客户端的流量生成器每秒发送数千个请求进行测试。

我想做的是与 this 类似的事情但使用 RMI。

基本上,如果服务器达到饱和,则停止接受/处理请求,以便它可以继续处理当前的请求。

这可能吗,还是我真的需要使用套接字来实现此目的?

提前致谢。

编辑:我还需要知道有多少请求在某个地方被拒绝(可能是客户端或服务器端)

最佳答案

RMI 为您提供了一种控制服务器套接字创建的方法,如果您控制客户端-服务器套接字的创建,您可以决定是否为传入请求提供服务,当然您可以监视服务的拒绝。这里需要扩展ServerSocket。 而如果你想拒绝“方法调用请求”,可以使用代理对象。

public class T {

    public static void main(String[] a) throws IOException {
        Queue<Socket> socks = new ConcurrentLinkedQueue<>();

        Registry registry = LocateRegistry.createRegistry(1099);
        IserverImpl roImpl = new IserverImpl();
        IService ro = Proxy.newProxyInstance(registry.getClass().getClassLoader(),
                        new Class[]{IService.class},
                        (proxy, method, args) -> {
                            if (isServerSaturationReached()) {
                                logRejection(method);
                                throw ReqRejectedByServerException();
                            }
                            return method.invoke(roImpl, args);
                        });

        Remote expRO = UnicastRemoteObject.exportObject(ro, 1100, null,
                        new RMIServerSocketFactory() {
                            @Override
                            public ServerSocket createServerSocket(int port) throws IOException {
                                return new MyServerSocket(port, socks);
                            }
                        });
        registry.bind("ro", expRO);

        Thread socksMgr = new Thread() {
            @Override
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(30000);
                        int sSize = socks.size();
                        for (int i = 0; i < sSize; i++) {
                            final Socket s = socks.remove();
                            try {
                                // server side RMI socket will be closed if client close socket
                                if (!s.isClosed())
                                    socks.offer(s);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        sSize = socks.size();
                        if (isServerSaturationReached(sSize))
                            for (int i = 0; i < sSize / 10; i++) {
                                try {
                                    final Socket sockToReject = socks.remove();
                                    reject(sockToReject); // sockToReject.close();
                                    logRejection(sockToReject);
                                } catch (IOException e) {
                                }
                            }
                    } catch (InterruptedException e) {
                        return;
                    }
                }
            }
        };
        socksMgr.setPriority(Thread.MAX_PRIORITY);
        socksMgr.setDaemon(true);
        socksMgr.start();
    }

    public static class MyServerSocket extends ServerSocket {

        private Queue<Socket> socks;

        public MyServerSocket(int port, Queue<Socket> socks) throws IOException {
            super(port);
            this.socks = socks;
        }

        @Override
        public Socket accept() throws IOException {
            while (!super.isClosed()) {
                Socket a = super.accept();
                if (isServerSaturationReached(socks.size())) {
                    reject(a); // a.close();
                    logRejection(a);
                    //...
                } else {
                    socks.offer(a);
                    return a;
                }
            }
            throw new SocketException("Socket is closed");
        }
    }
}

关于Java RMI : Rejecting requests when saturation is reached,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27132622/

相关文章:

java - scala/Serializable NoClassDefFoundError (RMI w/Scala)

java - 如何配置MULE Rmi?

java - Playframework JSR-303 验证 "field"没有对应的数据绑定(bind)访问器

java - 具有不同 Activity 的 RecyclerView

java - 如何在java中将文件读入字符串?

java - RMI中的rmic是什么?

java RMI无法运行服务器

java - 将字符串 x = "[]"映射到 JsonNode 会导致额外的引号(Spring Boot)

java - Netbeans 突然创建文件并将日志输出写入 c :\windows directory

java - 尝试生成 stub 文件时出错