You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置ring-jetty-adapter限制嵌入式Jetty的并发工作线程数

限制Ring Jetty Adapter工作线程并发数的实现方案

方案1:集成Jetty QoSFilter(你调研的方案)

ring-jetty-adapter支持通过:configurator参数自定义Jetty服务配置,无需web.xml即可注入QoSFilter,具体实现如下:

第一步:对齐依赖

在project.clj(Leiningen项目)或deps.edn(Clojure CLI项目)中添加Jetty Servlets依赖,版本需与你当前使用的ring-jetty-adapter内置的Jetty主版本保持一致,避免类冲突:

;; Leiningen 示例
[org.eclipse.jetty/jetty-servlets "你的Jetty版本号"]

注意:Jetty 11及以上版本使用jakarta.servlet包,Jetty 10及以下版本使用javax.servlet包,后续代码中的import语句需对应调整。

第二步:代码实现

(ns your-app.core
  (:require [ring.adapter.jetty :as jetty]
            [ring.util.servlet :as servlet])
  (:import (org.eclipse.jetty.servlet ServletContextHandler ServletHolder FilterMapping)
           (org.eclipse.jetty.servlets QoSFilter)
           ;; Jetty 10及以下替换为 jakarta -> javax
           (jakarta.servlet DispatcherType)
           (java.util EnumSet)))

;; 你的业务Ring Handler
(defn your-ring-handler [request]
  {:status 200
   :body "Hello World"})

;; Jetty自定义配置器
(defn jetty-configurator [^org.eclipse.jetty.server.Server server]
  (let [context (ServletContextHandler. ServletContextHandler.SESSIONS)
        ;; 配置QoSFilter,最大并发请求数和数据库连接池一致设为20
        qos-filter (doto (QoSFilter.)
                  (.setInitParameter "maxRequests" "20")
                  ;; 可选:请求排队最大超时时间,单位毫秒,超时返回503
                  (.setInitParameter "maxWait" "30000"))
        filter-holder (ServletHolder. qos-filter)
        filter-mapping (doto (FilterMapping.)
                         (.setFilterName "QoSFilter")
                         ;; 可按需修改为指定接口路径,无需全局限制
                         (.setPathSpecs (into-array String ["/*"]))
                         (.setDispatcherTypes (EnumSet/of DispatcherType/REQUEST)))]
    ;; 注入Ring业务Handler
    (.setServlet context (ServletHolder. (servlet/servlet your-ring-handler)) "/*")
    (.addFilter context filter-holder filter-mapping)
    (.setHandler server context)))

;; 启动Jetty服务
(jetty/run-jetty your-ring-handler
  {:port 8080
   :configurator jetty-configurator
   ;; 总线程池大小可以设为比20大,预留足够线程给 acceptor、selector 等非业务线程
   :max-threads 50})

方案2:Ring中间件层实现(轻量替代方案)

如果不需要复杂的QoS规则,可以直接在Ring中间件层通过信号量实现并发限制,无需依赖Jetty扩展包,实现更灵活:

(ns your-app.core
  (:require [ring.adapter.jetty :as jetty])
  (:import (java.util.concurrent Semaphore TimeUnit)))

;; 初始化信号量,许可数和数据库连接池一致为20
(def ^Semaphore request-semaphore (Semaphore. 20))

;; 并发限制中间件
(defn wrap-concurrency-limit [handler]
  (fn [request]
    ;; 尝试获取许可,最多等待30秒
    (if (.tryAcquire request-semaphore 30 TimeUnit/SECONDS)
      (try
        (handler request)
        (finally
          ;; 请求处理完成释放许可
          (.release request-semaphore)))
      ;; 超时返回503
      {:status 503
       :body "服务繁忙,请稍后重试"})))

;; 你的业务Handler,外层包装并发限制中间件
(def your-ring-handler
  (wrap-concurrency-limit
   (fn [request]
     {:status 200
      :body "Hello World"})))

;; 启动Jetty
(jetty/run-jetty your-ring-handler
  {:port 8080
   :max-threads 50})

内容的提问来源于stack exchange,提问作者Viktor Holmberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.16 12:24:09