LanguageTool 6.8 配置参数详解
LanguageTool 6.8 自建服务配置参数详解:三层配置入口、JVM 内存 512MB 约束与验证、请求限流 429 与超长 413 实测、ngram 模型与空目录陷阱、Nginx 反代接入实测、两档生产配置模板。
LanguageTool 6.8 配置参数详解
目标:系统梳理 LanguageTool 6.8 自建服务的全部配置入口与参数——JVM 内存(约束在 512MB 并验证)、请求限流与文本长度限制(429/413 实测)、缓存与线程、语言识别与 ngram 模型、规则控制、反代接入与日志诊断。全文在 Ubuntu 22.04 服务器(服务端口 8130,发行镜像
meyay/languagetool:6.8)实测,命令与回显照抄实录。
一、环境信息
- 操作系统:Ubuntu 22.04(x86_64)
- LanguageTool:6.8(GitHub 官方 tag 构建,发行镜像
meyay/languagetool:6.8) - 部署形态:Docker Compose,部署目录
/opt/languagetool/,宿主端口 8130 → 服务 8081(部署过程见 《LanguageTool 6.8 Docker Compose 部署实战》) - Java 运行时:Temurin 21.0.12+8(jlink 裁剪版,位于
/opt/java/customjre,不含 jps 工具) - 实验性 Nginx 反代:监听 8141 → 转发 8130(第六节实测)
- 本篇涉及的实测产物路径:运行时配置
/tmp/config.properties(实例内)
二、前置条件
- 已按 《LanguageTool 6.8 Docker Compose 部署实战》完成部署且服务健康:
docker compose -f /opt/languagetool/docker-compose.yml ps
# NAME STATUS PORTS
# languagetool-6.8-server Up 10 minutes (healthy) 0.0.0.0:8130->8081/tcp, [::]:8130->8081/tcp
- 本篇「参数查看/修改」以 compose 部署为主线;裸机 jar 部署的差异在各节用 ⚠️ 标注(差异点:环境变量由 entrypoint 处理,裸机时直接写
--config指向的 properties 文件)。 - 请求级参数(
language、level、enabledRules等,属每次 API 调用的参数而非服务端配置)不在本篇展开,见 《LanguageTool API 调用与运维实战(核心篇)》。
三、参数查看与修改方式
LanguageTool 服务端配置分三层,作用域从大到小依次为:
- 启动层(进程参数):JVM 参数与 HTTPServer 命令行参数(
--port、--public、--allow-origin、--languageModel等); - 服务端层(server.properties):
maxTextLength、requestLimit、cacheSize等键值对,控制全局行为; - 请求层(URL/表单参数):随每次
/v2/check调用传入,只影响该次请求。
compose 发行镜像在 1、2 层之上提供环境变量入口:JAVA_* 前缀拼 JVM 参数、langtool_ 前缀拼 server.properties 键,由 entrypoint 在每次启动时生成运行时配置文件 /tmp/config.properties。
3.1 查看当前生效配置
- 运行时配置文件(实测,默认部署):
docker exec languagetool-6.8-server cat /tmp/config.properties
实测回显(逐行):
fasttextBinary=/usr/bin/fasttext
fasttextModel=/fasttext/lid.176.bin
- 进程完整启动命令(含 JVM 参数):
docker exec languagetool-6.8-server ps -ef | grep '[H]TTPServer'
实测回显(进程参数完整照抄,busybox ps 的 PID/USER/TIME 三列):
7 language 1:36 java -Xms256m -Xmx512m -XX:+UseG1GC -XX:+UseStringDeduplication -Djna.tmpdir=/tmp -Dlogback.configurationFile=/tmp/logback.xml -cp .:languagetool-server.jar org.languagetool.server.HTTPServer --port 8081 --public --allow-origin * --config /tmp/config.properties
- entrypoint 拼装的 JVM 参数汇总(启动日志):
docker logs languagetool-6.8-server 2>&1 | grep 'Using JAVA_OPTS'
# INFO: Using JAVA_OPTS=-Xms256m -Xmx512m -XX:+UseG1GC -XX:+UseStringDeduplication
- 服务端命令行参数全集(官方
--help实测获取,不影响运行中的服务):
docker exec languagetool-6.8-server sh -c 'cd /languagetool && java -cp languagetool-server.jar org.languagetool.server.HTTPServer --help' 2>/dev/null
输出节选(实测,logback 初始化日志已略):
Usage: HTTPServer [--config propertyFile] [--port|-p port] [--public]
--config FILE a Java property file (one key=value entry per line) with values for:
'maxTextLength' - maximum text length, longer texts will cause an error (optional)
'maxTextHardLength' - maximum text length, applies even to users with a special secret 'token' parameter (optional)
'maxCheckTimeMillis' - maximum time in milliseconds allowed per check (optional)
'maxErrorsPerWordRate' - checking will stop with error if there are more rules matches per word (optional)
'maxSpellingSuggestions' - only this many spelling errors will have suggestions for performance reasons (optional,
affects Hunspell-based languages only)
'maxCheckThreads' - maximum number of threads working in parallel (optional)
'cacheSize' - size of internal cache in number of sentences (optional, default: 0)
'cacheTTLSeconds' - how many seconds sentences are kept in cache (optional, default: 300 if 'cacheSize' is set)
'requestLimit' - maximum number of requests per requestLimitPeriodInSeconds (optional)
'requestLimitInBytes' - maximum aggregated size of requests per requestLimitPeriodInSeconds (optional)
'timeoutRequestLimit' - maximum number of timeout request (optional)
'requestLimitPeriodInSeconds' - time period to which requestLimit and timeoutRequestLimit applies (optional)
'languageModel' - a directory with '1grams', '2grams', '3grams' sub directories per language which contain a Lucene index
each with ngram occurrence counts; activates the confusion rule if supported (optional)
'fasttextModel' - a model file for better language detection (optional), see
https://fasttext.cc/docs/en/language-identification.html
'fasttextBinary' - compiled fasttext executable for language detection (optional), see
https://fasttext.cc/docs/en/support.html
'maxWorkQueueSize' - reject request if request queue gets larger than this (optional)
'rulesFile' - a file containing rules configuration, such as .languagetool.cfg (optional)
'blockedReferrers' - a comma-separated list of HTTP referrers (and 'Origin' headers) that are blocked and will not be served (optional)
'premiumOnly' - activate only the premium rules (optional)
'disabledRuleIds' - a comma-separated list of rule ids that are turned off for this server (optional)
'pipelineCaching' - set to 'true' to enable caching of internal pipelines to improve performance
'maxPipelinePoolSize' - cache size if 'pipelineCaching' is set
'pipelineExpireTimeInSeconds' - time after which pipeline cache items expire
'pipelinePrewarming' - set to 'true' to fill pipeline cache on start (can slow down start a lot)
'trustXForwardForHeader' - set this to 'true' if you run the server behind a reverse proxy and want the
request limit to work on the original IP addresses provided by the 'X-forwarded-for' HTTP header,
usually set by the proxy
(--help 后续还有 --port, -p PRT、--public、--allow-origin [ORIGIN]、--verbose, -v、--languageModel、--premiumAlways 以及拼写检查专用语言扩展 lang-xx/lang-xx-dictPath 与 suggestionsEnabled 说明,语义见第四节参数总览表。)
3.2 修改配置并验证生效
以「限制单请求文本 1000 字符 + 每 60 秒最多 3 次请求」为例,compose 的 environment 中加入:
environment:
langtool_maxTextLength: "1000"
langtool_requestLimit: "3"
langtool_requestLimitPeriodInSeconds: "60"
重建实例使配置生效:
cd /opt/languagetool && docker compose up -d --force-recreate
# Container languagetool-6.8-server Starting
# Container languagetool-6.8-server Started
验证一:配置文件已带新键(实测回显):
docker exec languagetool-6.8-server cat /tmp/config.properties
requestLimit=3
requestLimitPeriodInSeconds=60
maxTextLength=1000
fasttextBinary=/usr/bin/fasttext
fasttextModel=/fasttext/lid.176.bin
注:键的出现顺序由 entrypoint 遍历环境变量生成,每次重建可能不同(实测两次重建键序不同),校验以「键值对是否齐全」为准,勿以顺序为准。
验证二:行为实测(回显见第五节 5.2)。
⚠️ 注意:改 environment 后必须
--force-recreate(或down && up -d),只restart不会重新读取 compose 环境变量——这是「改了配置不生效」的最常见原因。
四、参数总览
镜像层环境变量(meyay/languagetool 发行镜像 entrypoint 定义,默认值经镜像 inspect 实测核对):
| 环境变量 | 默认值 | 作用 |
|---|---|---|
JAVA_XMS | 256m | JVM 堆下限 |
JAVA_XMX | 1536m | JVM 堆上限(本专栏实测压到 512m) |
JAVA_GC | ShenandoahGC | GC 选择:SerialGC/ParallelGC/ParNewGC/G1GC/ZGC/ShenandoahGC |
JAVA_OPTS | 空 | 自定义完整 JVM 参数;设置后其余 JAVA_* 失效 |
LISTEN_PORT | 8081 | 服务监听口 |
download_ngrams_for_langs | none | 启动时自动下载 ngram 的语言列表(en/de/es/fr/nl,逗号分隔) |
langtool_languageModel | /ngrams | ngram 数据目录;目录非空才写入配置(空目录陷阱见 5.4) |
langtool_fasttextBinary | /usr/bin/fasttext | fastText 可执行文件路径 |
langtool_fasttextModel | /fasttext/lid.176.bin | fastText 模型路径;缺失时自动下载 |
langtool_<键名> | — | 任意 server.properties 键的前缀注入方式 |
MAP_UID / MAP_GID | 783 / 783 | 实例内运行服务的用户/组 |
LOG_LEVEL | INFO | 日志级别:TRACE/DEBUG/INFO/WARN/ERROR |
LOGBACK_CONFIG | ./logback.xml | logback 配置位置 |
DISABLE_FILE_OWNER_FIX | false | 关闭挂载目录属主修正(非 root 模式自动隐含) |
DISABLE_FASTTEXT | false | 关闭 fastText(不下载模型、不启用语言识别增强) |
DEBUG_ENTRYPOINT | 空 | true 时输出 entrypoint 调试日志 |
CONTAINER_MODE | default | download-only 供 K8s initContainer 预下载模型用 |
server.properties 服务端键(语义以官方 --help 原文为准,见 3.1;按用途归类):
| 分组 | 键 |
|---|---|
| 请求限额 | maxTextLength、maxTextHardLength、requestLimit、requestLimitInBytes、requestLimitPeriodInSeconds、timeoutRequestLimit、maxWorkQueueSize |
| 检查过程 | maxCheckTimeMillis、maxErrorsPerWordRate、maxSpellingSuggestions、maxCheckThreads、suggestionsEnabled |
| 缓存 | cacheSize、cacheTTLSeconds、pipelineCaching、maxPipelinePoolSize、pipelineExpireTimeInSeconds、pipelinePrewarming |
| 语言与模型 | languageModel、fasttextModel、fasttextBinary、lang-xx、lang-xx-dictPath |
| 规则控制 | rulesFile、disabledRuleIds、premiumOnly |
| 网络与代理 | blockedReferrers、trustXForwardForHeader |
HTTPServer 命令行参数:--config FILE、--port/-p、--public、--allow-origin [ORIGIN]、--verbose/-v、--languageModel DIR(覆盖 properties 同名键)、--premiumAlways。
三层关系解读:命令行 --languageModel 优先于 properties 同名键;properties 键整体可由镜像 langtool_ 前缀环境变量生成;请求层参数(如 enabledRules)只叠加在服务端配置之上,服务端 disabledRuleIds 关掉的规则请求层无法再打开。
五、核心参数分类详解
5.1 JVM 内存参数(256–512MB 约束)
LanguageTool 是常驻 JVM 服务,语言模块、词典与规则加载后内存占用明显。镜像默认 JAVA_XMX=1536m,对小内存服务器偏大;本专栏统一约束为堆 256–512MB:
environment:
JAVA_XMS: 256m
JAVA_XMX: 512m
JAVA_GC: G1GC
生效验证(三层证据,实测回显):
- 启动日志:
INFO: Using JAVA_OPTS=-Xms256m -Xmx512m -XX:+UseG1GC -XX:+UseStringDeduplication; - 进程参数:
ps -ef | grep '[H]TTPServer'可见java -Xms256m -Xmx512m -XX:+UseG1GC ...(完整回显见 3.1); - 运行稳定:512m 堆 + G1GC 下常规校对请求持续 200(后续各篇实测均在此配置上完成)。
要点:
- 该镜像的 JRE 经 jlink 裁剪(
/opt/java/customjre/bin/仅java jdb jrunscript jwebserver keytool),没有jps,堆验证用ps -ef | grep '[H]TTPServer'或docker logs的Using JAVA_OPTS=行; JAVA_OPTS一旦设置即接管整个 JVM 参数串(镜像文档明示),适合需要加-XX:+HeapDumpOnOutOfMemoryError等参数的场景,例如JAVA_OPTS: "-Xms256m -Xmx512m -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp";- 堆外的内存开销(词典 mmap、fastText 子进程、JVM 元空间)另计,物理内存按堆上限的 1.5~2 倍规划。
💡 技术拓展:JVM 垃圾收集器在 512MB 小堆下的常见选择对比——
GC 特点 小堆服务适用性 SerialGC 单线程,无并行开销 内存最省,适合 ≤512MB 且低并发 G1GC 分 region 并发标记,停顿可控 通用推荐,本专栏实测采用 ShenandoahGC 低停顿并发整理 镜像默认;小堆下与 G1 差异不大 ZGC 亚毫秒停顿 堆大时才发挥优势,小堆不划算 本文实际采用 G1GC:512MB 堆 + 每请求毫秒级耗时(《LanguageTool API 调用与运维实战(核心篇)》9.2 节实测 30~100ms 量级)场景下停顿已非瓶颈。
5.2 请求限额参数(429/413 实测)
自建服务对外暴露时,限额参数是第一道闸门。实测组合:
environment:
langtool_maxTextLength: "1000"
langtool_requestLimit: "3"
langtool_requestLimitPeriodInSeconds: "60"
requestLimit 限流实测(重建实例后连续 4 次请求):
for i in 1 2 3 4; do curl -s -o /dev/null -w "第${i}次: HTTP:%{http_code}\n" \
-d "language=en-US" -d "text=hello world" http://127.0.0.1:8130/v2/check; done
实测回显(逐行):
第1次: HTTP:200
第2次: HTTP:200
第3次: HTTP:200
第4次: HTTP:429
第 4 次的响应体(实测照抄):
Error: Access from 10.89.56.1 denied: Client request limit of 3 requests per 60 seconds exceeded
maxTextLength 超长实测(窗口期过后提交 1200 字符文本):
Error: Your text exceeds the limit of 1000 characters (it's 1200 characters). Please submit a shorter text.
状态码 HTTP 413;同窗口内 900 字符文本正常返回 HTTP 200。
参数要点:
requestLimit+requestLimitPeriodInSeconds:按来源 IP(直连时为对端地址)限流,超限返回 429;上例报错中的10.89.56.1即服务看到的请求来源地址;maxTextLength:单请求字符上限,超限 413;maxTextHardLength是连持有token的特权用户也不能超的硬顶;requestLimitInBytes:按时间窗内请求字节总量限流(防大请求打满带宽);maxCheckTimeMillis:单次检查耗时上限,超时中断(防恶意构造文本拖死规则引擎);maxWorkQueueSize:排队队列深度上限,超过直接拒绝(防雪崩);- 生产建议:内网低信任环境给
requestLimit=60~120/60s、maxTextLength=20000;公网裸暴露则参考官方公共 API 的口径(20 次/分/IP、20KB/请求,见《LanguageTool 介绍与选型指南》篇溯源数据)。
两个限流实测补充(同次实测确认):
- 窗口内已有前序请求会提前触发 429:本节 4 连发前若窗口内已有验证请求,第 3 次即 429(实测出现过 200/200/429/429 序列)——测试限流务必用干净窗口(等满 60 秒再连发)。
GET /v2/languages与/v2/check计入同一个限额桶(实测经反代 8141 的请求与直连 8130 互相消耗限额)——健康探测与语言清单轮询频繁的部署,反代层应对健康检查路径单独放行。
5.3 缓存与线程参数
| 参数 | 默认 | 说明与建议 |
|---|---|---|
cacheSize | 0(关) | 句子级缓存条数;重复文本多的场景(如自动保存触发重复校对)建议 128~512 |
cacheTTLSeconds | 300(cacheSize>0 时) | 缓存存活秒数 |
maxCheckThreads | 按核 | 并行检查线程数;512MB 堆建议 4~10,过高会撑爆堆 |
pipelineCaching | 关 | 缓存内部检查管线(按语言+规则组合),API 型负载收益明显 |
maxPipelinePoolSize | — | 管线缓存条目数(pipelineCaching=true 时生效) |
pipelineExpireTimeInSeconds | — | 管线缓存过期时间 |
pipelinePrewarming | 关 | 启动时预热管线;首次请求变快,但启动显著变慢(官方原文「can slow down start a lot」) |
suggestionsEnabled | true | 是否生成替换建议;只判断对错不需要建议时可关,省 CPU |
maxSpellingSuggestions | — | 拼写错误给建议的数量上限(hunspell 系语言),官方注明是性能保护参数 |
实测默认态:maxCheckThreads 未配置时服务启动日志显示 Setting up thread pool with 10 threads(4.4 节日志实录)。
5.4 语言识别与 ngram 模型参数
语言识别链路由两个 fastText 参数驱动(默认已内置,见 3.1 实测配置回显):
fasttextBinary=/usr/bin/fasttext:可执行文件(镜像内置);fasttextModel=/fasttext/lid.176.bin:模型文件(首次启动自动下载约 131MB,落/fasttext卷持久化)。
💡 技术拓展:语言识别(language identification)的常见实现对比——
实现 原理 精度/开销 字符 ngram 统计(内置兜底) 语言特征字符频率 快,短文本精度一般 fastText lid.176.bin 子词级分类模型 176 语种、短文本高置信(API 篇实测法语 0.99) 请求方显式指定 language 不做识别 零开销、最可控 本方案实际采用 fastText(镜像默认)+ 请求方显式指定双轨;
DISABLE_FASTTEXT=true时退回纯内置识别。
ngram 混淆规则数据由三个参数控制:
langtool_languageModel(即 properties 的languageModel):指向1grams/2grams/3gramsLucene 索引的父目录;download_ngrams_for_langs:启动时自动下载的语言(en/de/es/fr/nl);--languageModel(命令行):优先级高于 properties 键。
空目录陷阱(重要,含 A/B 实测):entrypoint 只在 langtool_languageModel 目录非空时才把 languageModel 写入 config.properties;目录为空则整个键省略。原因是 LanguageTool 服务端行为:配置了 languageModel 但目录里没有该语言数据时,会静默禁用该语言的拼写类规则(MORFOLOGIK_RULE_* 等),返回 matches: [] 且 HTTP 200、无任何告警(官方镜像 issue #179 记录)。A/B 对照实测(本机验证,文本 This are a test. teh end is near.):
| 形态 | /tmp/config.properties | teh 拼写检出 |
|---|---|---|
A:仅挂 nl 数据(languageModel=/ngrams) | 含 languageModel=/ngrams | 不检出(en 拼写被静默禁用,matches 仅 2 条语法) |
| B:无 languageModel(默认态) | 仅 fasttext 两键 | 检出 MORFOLOGIK_RULE_EN_US |
结论:不用 ngram 就保持目录为空;要挂载就必须放所有在用语言的完整数据(<语言>/1grams、2grams、3grams)——只挂部分语言会禁用其余语言的拼写检查。API 侧完整验证见 《LanguageTool API 调用与运维实战(核心篇)》。
挂载与下载操作见 《LanguageTool 6.8 Docker Compose 部署实战》第八节(含 nl 数据 2.4GB 实测与挂载后行为验证)。
5.5 规则控制参数
disabledRuleIds:服务端全局关停规则(逗号分隔 rule id),被关规则对所有请求失效且不可被请求层打开;适合关停误报率高的规则;rulesFile:外置规则配置文件(如.languagetool.cfg),做规则级微调;premiumOnly:只激活 premium 规则(自建开源版无 premium 规则集,该键实际空转,保留给私有构建用);lang-xx/lang-xx-dictPath:为不内置的语言加「纯拼写检查」支持——lang-tr=Turkish+lang-tr-dictPath=/path/tr.dic(同目录还需common_words.txt高频词表,用于语言检测),官方--help原文载明。
请求级 enabledRules/disabledRules/enabledOnly 与服务端的分工:服务端做「基线裁剪」,请求层做「按次微调」,实测演示见 《LanguageTool API 调用与运维实战(核心篇)》5.5 节。
5.6 网络与反代接入参数
服务内置 HTTP(无 TLS、无认证),公网/受信边界暴露一律走反代。Nginx 反代实测(服务器监听 8141,转发 8130):
server {
listen 8141;
server_name lt.example.com;
client_max_body_size 2m;
location /v2/ {
proxy_pass http://127.0.0.1:8130;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 120s;
}
}
实测回显:
curl -s -o /dev/null -w 'HTTP:%{http_code}\n' http://127.0.0.1:8141/v2/languages
# HTTP:200
curl -s -d "language=en-US" -d "text=This are an test." http://127.0.0.1:8141/v2/check | python3 -m json.tool | grep '"id"'
# "id": "THIS_NNS",
# "id": "PLURAL_VERB_AFTER_THIS",
# "id": "EN_A_VS_AN"
排障实录(实测复现):若把 proxy_pass 写成带 URI 的 proxy_pass http://127.0.0.1:8130/;(注意结尾的 /),Nginx 会做前缀替换——请求 /v2/languages 到后端变成 /languages(/v2/ 前缀被剥掉),实测返回 HTTP 400 + API 提示文本(curl -s http://127.0.0.1:8143/v2/languages → Error: This is the LanguageTool API. You have not specified any parameters...,直连 http://127.0.0.1:8130/languages 对照同样 400,确认为路径改写所致)。改为不带 URI 的 proxy_pass http://127.0.0.1:8130; 原样透传后恢复正常(8141 形态实测 200)。LanguageTool 的路径敏感,反代不做路径改写是最稳形态。
反代相关服务端参数:
trustXForwardForHeader=true:服务在反代后时必须开启,否则requestLimit按反代地址统一计数(所有用户共享一个桶,正常用户被误伤);开启后按X-Forwarded-For里的原始 IP 限流;blockedReferrers:拒绝指定 Referer/Origin 来源(防盗用);--allow-origin [ORIGIN]:CORS 头控制。不设参数值即*(任意站点浏览器直连,镜像默认形态);指定值如--allow-origin "https://my-website.org"则只允许该站点 JS 直连;--public:仅监听本机改为对外监听(镜像默认已带)。裸机部署时不加--public服务只接受本机连接——这是官方默认的访问安全边界。
5.7 用户与权限参数
| 参数 | 默认 | 说明 |
|---|---|---|
MAP_UID/MAP_GID | 783/783 | 实例内运行服务的用户;挂载卷权限问题首选把宿主目录 chown -R 783:783 |
DISABLE_FILE_OWNER_FIX | false | 启动时自动修正 ngrams/fasttext 目录属主;非 root 运行时自动隐含为 true |
| 非 root 运行 | root 启动 | compose 加 user: "783:783" 即以非特权身份运行(官方推荐形态),需自行保证卷属主 |
5.8 日志与诊断参数
LOG_LEVEL:INFO 起步;排障时调DEBUG(输出规则加载明细),生产建议 WARN 级别减噪——注意调整后必须重建实例;LOGBACK_CONFIG:logback 配置位置,需自定义日志输出格式/文件时挂载自定义 logback.xml 并指到这里;DEBUG_ENTRYPOINT=true:entrypoint 层调试(模型下载、配置拼装过程);- 服务端每请求一行
Handled request in <耗时>ms; sending code <状态码>日志(INFO 级即可见,本专栏多篇实测引用),是观察限流与耗时的第一现场。
六、生产配置模板
按内存分两档给可直接落地的 compose environment 模板(数据卷与端口见部署篇)。
档位 A:4GB 内存、低并发内网服务(本专栏实测同款)
environment:
JAVA_XMS: 256m
JAVA_XMX: 512m
JAVA_GC: G1GC
LOG_LEVEL: WARN
langtool_maxTextLength: "20000"
langtool_requestLimit: "120"
langtool_requestLimitPeriodInSeconds: "60"
langtool_cacheSize: "256"
langtool_maxCheckThreads: "8"
langtool_trustXForwardForHeader: "true"
适用:8~10 人内网写作/工单校对;不挂 ngram;文本单请求 2 万字符内。请求限额按来源 IP 60 秒 120 次,明显宽于官方公共 API(20 次/分/IP),够自动化工具轮询。
档位 B:8GB 内存、挂 ngram 的质量优先服务
environment:
JAVA_XMS: 512m
JAVA_XMX: 1024m
JAVA_GC: G1GC
LOG_LEVEL: WARN
langtool_maxTextLength: "40000"
langtool_requestLimit: "240"
langtool_requestLimitPeriodInSeconds: "60"
langtool_cacheSize: "512"
langtool_maxCheckThreads: "10"
langtool_pipelineCaching: "true"
langtool_maxPipelinePoolSize: "64"
langtool_pipelineExpireTimeInSeconds: "3600"
langtool_trustXForwardForHeader: "true"
download_ngrams_for_langs: "en"
适用:浏览器插件全员接入 + 编辑器集成;ngram 激活英语混淆规则;管线缓存对同语言重复请求省 30% 以上 CPU(官方机制,具体收益以自身负载压测为准)。注意 ngram 数据盘占用(en 6GB+)与下载时长。
⚠️ 注意:两档模板均假设服务位于反代之后(
trustXForwardForHeader才有意义);直连形态删掉该键。
七、常见问题(FAQ)
Q1:改了 compose 环境变量但配置没生效?
docker compose up -d --force-recreate 重建(仅 restart 不重读环境变量)。验证链:cat /tmp/config.properties 看键是否出现 → docker logs 看 Using JAVA_OPTS= → 请求实测行为(5.2 的 429/413 即最硬证明)。
Q2:返回 429 Too Many Requests?
触发了 requestLimit(按来源 IP 限流)。确认报错原文里的来源 IP 是否符合预期;反代后务必开 trustXForwardForHeader=true,否则所有人共享反代的限额。窗口期过自动恢复。
Q3:返回 413 且提示 text exceeds the limit?
maxTextLength/maxTextHardLength 限制。官方公共 API 口径是 20KB/请求;自建按业务放行,超长文本应分段提交。
Q4:挂了 ngrams 目录后拼写检查悄悄失效?
空目录陷阱(5.4):languageModel 指向无数据目录时服务端静默禁用拼写类规则。处理:补齐数据或清空目录(entrypoint 便不再写入该键)。
Q5:语言代码报 400?
Error: 'xx-INVALID' is not a language code known to LanguageTool...——用 /v2/languages 返回清单里的 longCode(如 en-US、zh-CN、pt-BR),变体码与基础码含义见 《LanguageTool API 调用与运维实战(核心篇)》5.1 节实测。
Q6:实例内没有 jps 怎么验证堆参数?
该镜像 JRE 经 jlink 裁剪、不含 jps(/opt/java/customjre/bin/ 仅 5 个工具)。用 ps -ef | grep '[H]TTPServer' 看完整进程参数(3.1 实测回显),或看启动日志 Using JAVA_OPTS= 行。
Q7:反代后所有请求 400「This is the LanguageTool API...」?
proxy_pass 带了 URI(如 http://127.0.0.1:8130/;)导致前缀改写、后端收到错误路径。改为不带 URI 的 proxy_pass http://127.0.0.1:8130;(5.6 实测排障)。
八、参考链接
- 官方自建服务说明(server.properties 与启动参数):https://dev.languagetool.org/http-server
- 官方 HTTP API 交互式文档:https://languagetool.org/http-api/swagger-ui/
- 发行镜像参数文档(环境变量表):https://github.com/meyayl/docker-languagetool
- ngram 语言模型官方说明:https://dev.languagetool.org/finding-errors-using-n-gram-data
- ngram 空目录陷阱 issue:https://github.com/meyayl/docker-languagetool/issues/179
- 公共 API 限流口径(自建限额参考):https://dev.languagetool.org/public-http-api
- 平台内相关篇目:《LanguageTool Docker Compose 部署实战》(部署与持久化)、《LanguageTool API 调用与运维实战(核心篇)》(请求参数实测与错误处理)、《LanguageTool 介绍与选型指南》(选型对比)。