__BlueCat 2019-07-23 10:44 采纳率: 0%
浏览 476

zeromq 服务端多线程在数据量大一点的情况下出现问题,跪求大神解答

zeromq 服务端开启了20个线程,客服端会发送6000个请求过来; 在处理1000个请求的时候,速度很快,一口气就跑完了, 在处理一千到三千的请求的时候,中间总是停一会,跑一会, 到了三千以后停的时间越来越长,到四千左右就不动了. 有时候会报"gc开销过大",调了gc之后.还是没有多大的作用, 但是呢:当我把服务端的线程只开启一个的时候,就能顺利跑完, 下面是服务端的代码

/**
 *  多线程 NLP 服务器
 */
public class mtserver {
    /*默认为20个NLP线程*/
    static Integer WORKERNUM = 20;

    private static class HeronlpWorker extends Thread {
        private ZContext context;
        private MyUncaughtExceptionhandler myUncaughtException;

        public void setMyUncaughtException(MyUncaughtExceptionhandler myUncaughtException) {
            this.myUncaughtException = myUncaughtException;
        }

        private HeronlpWorker(ZContext context) {
            this.context = context;
        }

        @Override
        public void run() {
            Socket socket = context.createSocket(SocketType.REP);
            myUncaughtException.setSkt(socket);
            socket.connect("inproc://workers");
            HeroNLP heroNLP = new HeroNLP();
            String result = null;
            String msgType = "";
            while (true) {
                try {
                    //接收命令
                    String command = socket.recvStr(0).trim();
                    System.out.println(Thread.currentThread().getName() + " Received request: [" + command + "]");
                    String content = null;
                    switch (command){
                        //分词
                        case "SEGMENT":
                            content = socket.recvStr(0).trim();
                            List<Term> terms = NLP.segment(content);
                            result = listToString(terms, " ");
                            break;
                        default:
                            while (socket.hasReceiveMore()){
                                socket.recvStr(0).trim();
                            }
                            result = "FAILED: 未匹配到命令!";
                            break;

                    }
                } catch (Exception e) {
                    result = "FAILED:" + e.getMessage();
                }

                // 给客户端返回结果(C字符串)
                System.out.println("是否有异常: " + result.contains("FAILED:"));
                if(result.contains("FAILED:")){
                    msgType = "FAILED";
                }
                socket.send(msgType, 2);
                socket.send(result, 0);
            }
        }

    }
    public static void main(String[] args) {
        try (ZContext context = new ZContext()) {
           //前端--router
            Socket clients = context.createSocket(SocketType.ROUTER);
            boolean bind = clients.bind("tcp://*:9002");
            //后端--dealer
            Socket workers = context.createSocket(SocketType.DEALER);
            workers.bind("inproc://workers");

            //后端启动20个服务线程
            for (int thread_nbr = 0; thread_nbr < WORKERNUM; thread_nbr++) {
                Thread nlpworker = new HeronlpWorker(context);
                MyUncaughtExceptionhandler myUncaughtExceptionhandler = new MyUncaughtExceptionhandler();
                ((HeronlpWorker) nlpworker).setMyUncaughtException(myUncaughtExceptionhandler);
                nlpworker.setUncaughtExceptionHandler(myUncaughtExceptionhandler);
                nlpworker.start();
            }
            ZMQ.proxy(clients, workers, null);
        }
    }
  • 写回答

1条回答 默认 最新

  • 你知我知皆知 2024-08-10 20:00
    关注

    以下回答参考 皆我百晓生券券喵儿 等免费微信小程序相关内容作答,并由本人整理回复。

    从您提供的代码来看,服务端使用了ZMQ作为消息队列和协程管理器。当客户向服务端发送请求时,服务端会将这些请求发送给所有可用的NLP线程进行处理。

    以下是一些可能导致服务端性能问题的原因:

    1. 线程数量:在您的代码中,服务端设置了20个线程来处理请求。虽然这可能足以满足大多数场景的需求,但在处理大量请求时,可能会导致资源消耗过快。

    2. 线程池:在Java中,默认情况下,ZMQ不提供线程池功能。因此,服务端只能通过手动创建并管理线程来确保响应的速度。这种做法可能导致内存泄漏或线程数过多的问题。

    3. GC 开销:如果服务端的线程数太多,可能会触发垃圾回收(Garbage Collection),这会导致系统性能下降。为了应对这种情况,您可以考虑调整线程数或者启用线程池。

    4. 负载均衡:如果服务端有多个线程,但每个线程的任务分配不均,可能会导致某些线程长时间等待而其他线程却忙于完成任务。这可能是由于线程间通信效率低下或线程调度不当造成的。

    5. 异步编程:在处理大量请求时,使用异步编程模式可能会降低响应时间。然而,在某些情况下,这种方式可能导致响应延迟,尤其是在线程池设置不足的情况下。

    要解决这些问题,建议尝试以下方法之一:

    • 减少线程数量:根据实际需求合理地调整线程数。
    • 启用线程池:使用Java的java.util.concurrent.ExecutorService实现线程池,并指定适当的策略(如BlockingQueue)以优化性能。
    • 负载均衡:使用Java的java.net.ServerSocketjava.net.SocketFactory来配置负载均衡策略。
    • 异步编程:考虑使用如Spring Boot中的@Async注解、Kafka等工具库来提高响应速度。

    如果您能提供更具体的上下文信息(例如,何时遇到问题以及具体错误信息),我可能能够提供更加针对性的帮助。

    评论

报告相同问题?

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀