193 lines
6.0 KiB
Markdown
193 lines
6.0 KiB
Markdown
# Monica LSP Gateway
|
||
|
||
面向微服务场景的 LSP 网关(Gin),当前支持:
|
||
- Go: `gopls`
|
||
- JavaScript / TypeScript: `typescript-language-server --stdio`
|
||
|
||
网关职责:
|
||
- 对外提供 HTTP + WebSocket 接口
|
||
- 对内通过 JSON-RPC / LSP over stdio 驱动语言服务器
|
||
- 按 `language + sessionId` 维护长生命周期会话
|
||
- 会话空闲自动回收(TTL)
|
||
|
||
## 相关文档
|
||
|
||
- Spring Cloud Gateway 对接:`docs/spring-cloud-gateway-integration.md`
|
||
- Java + Nacos 对接:`docs/java-nacos-integration-guide.md`
|
||
- 前端对接:`docs/frontend-integration.md`
|
||
- 前端经 Gateway 对接(AIOJ):`../docs/lsp-golang-gateway-frontend-integration.md`
|
||
|
||
## 运行
|
||
|
||
```bash
|
||
go mod tidy
|
||
go run ./cmd/server
|
||
```
|
||
|
||
默认地址:`http://127.0.0.1:8080`
|
||
|
||
## 配置文件(推荐)
|
||
|
||
后端现在支持 JSON 配置文件:
|
||
|
||
1. 复制 `config.example.json` 为 `config.json`
|
||
2. 修改你需要的字段
|
||
3. 启动服务(会自动读取当前目录 `config.json`)
|
||
|
||
```bash
|
||
cp config.example.json config.json
|
||
go run ./cmd/server
|
||
```
|
||
|
||
也可以显式指定路径:
|
||
|
||
```bash
|
||
CONFIG_FILE=./config.local.json go run ./cmd/server
|
||
```
|
||
|
||
优先级为:`默认值 < 配置文件 < 环境变量`。
|
||
也就是说你可以把大部分配置放在文件里,临时参数再用环境变量覆盖。
|
||
|
||
## 企业化配置(环境变量)
|
||
|
||
- `PORT`:默认 `8080`
|
||
- `WORKSPACE_DIR`:LSP 工作目录,默认当前目录
|
||
- `CORS_ALLOW_ORIGIN`:默认 `*`
|
||
- `LSP_API_TOKEN`:可选,设置后需在请求头传 `X-API-Key`
|
||
- `REQUEST_TIMEOUT`:单请求超时,默认 `10s`
|
||
- `MAX_BODY_BYTES`:请求体上限,默认 `2097152`(2MB)
|
||
- `SESSION_TTL`:会话空闲回收时间,默认 `20m`
|
||
- `SESSION_CLEANUP_INTERVAL`:清理周期,默认 `2m`
|
||
- `MAX_SESSIONS`:最大会话数,默认 `256`
|
||
- `ENABLE_REDIS_STICKY`:是否启用 Redis 会话外置与粘性路由,默认 `true`
|
||
- `REDIS_ADDR`:默认 `10.0.0.10:6379`
|
||
- `REDIS_DB`:默认 `1`
|
||
- `REDIS_PASSWORD`:默认空
|
||
- `REDIS_KEY_PREFIX`:默认 `lsp-gateway`
|
||
- `INSTANCE_ID`:实例唯一标识(建议由部署系统注入)
|
||
- `INSTANCE_URL`:实例可回源地址(用于路由提示),默认 `http://127.0.0.1:${PORT}`
|
||
- `INSTANCE_TTL`:实例注册 TTL,默认 `30s`
|
||
- `INSTANCE_HEARTBEAT_INTERVAL`:实例心跳周期,默认 `10s`
|
||
- `ENABLE_NACOS_REGISTER`:是否启用 Nacos SDK 注册,默认 `false`
|
||
- `NACOS_SERVER_ADDR`:Nacos 地址,默认 `10.0.0.10:8848`
|
||
- `NACOS_NAMESPACE`:Nacos namespace,默认空(public)
|
||
- `NACOS_GROUP`:Nacos group,默认 `DEFAULT_GROUP`
|
||
- `NACOS_SERVICE_NAME`:Nacos 服务名,默认 `lsp-gateway`
|
||
- `NACOS_CLUSTER_NAME`:可选 clusterName
|
||
- `NACOS_USERNAME`:Nacos 用户名,可空
|
||
- `NACOS_PASSWORD`:Nacos 密码,可空
|
||
- `NACOS_IP`:实例注册 IP(建议注入 Pod/主机内网 IP)
|
||
- `NACOS_PORT`:实例注册端口,默认取 `PORT`
|
||
- `NACOS_EPHEMERAL`:是否临时实例,默认 `true`
|
||
- `APP_NAME`:日志应用名,默认 `lsp-gateway`
|
||
- `APP_ENV`:运行环境,默认 `dev`
|
||
- `LOG_PATH`:日志根目录,默认 `./logs/${APP_NAME}`
|
||
- `LOG_LEVEL`:日志级别(`debug/info/warn/error`),默认 `info`
|
||
- `LOG_MAX_SIZE_MB`:单文件滚动阈值(MB),默认 `100`
|
||
- `LOG_MAX_BACKUPS`:滚动文件保留数量,默认 `31`
|
||
- `LOG_MAX_AGE_DAYS`:日志保留天数,默认 `31`
|
||
- `LOG_COMPRESS`:滚动文件是否压缩,默认 `true`
|
||
- `LOG_CONSOLE_ENABLED`:是否输出控制台,默认 `true`
|
||
- `TRUSTED_PROXIES`:受信代理列表(逗号分隔 IP/CIDR),默认空(不信任代理头)
|
||
- `REMOTE_IP_HEADERS`:客户端 IP 头列表(逗号分隔),默认 `X-Forwarded-For,X-Real-IP`
|
||
- `FORWARDED_BY_CLIENT_IP`:是否从代理头解析客户端 IP,默认 `true`
|
||
|
||
语言服务器命令(可替换为企业内部镜像/封装):
|
||
- `GO_LSP_COMMAND`,`GO_LSP_ARGS`
|
||
- `JAVASCRIPT_LSP_COMMAND`,`JAVASCRIPT_LSP_ARGS`
|
||
- `TYPESCRIPT_LSP_COMMAND`,`TYPESCRIPT_LSP_ARGS`
|
||
|
||
默认 JS/TS 命令:
|
||
- `typescript-language-server --stdio`
|
||
|
||
Nacos SDK 注册示例:
|
||
|
||
```bash
|
||
ENABLE_NACOS_REGISTER=true
|
||
NACOS_SERVER_ADDR=10.0.0.10:8848
|
||
NACOS_USERNAME=nacos
|
||
NACOS_PASSWORD=nacos
|
||
NACOS_SERVICE_NAME=lsp-gateway
|
||
NACOS_GROUP=DEFAULT_GROUP
|
||
NACOS_IP=10.0.2.15
|
||
NACOS_PORT=8080
|
||
```
|
||
|
||
日志输出说明(参考 Logback):
|
||
- 访问日志、业务日志都会写入文件和控制台(可关)。
|
||
- 日志目录结构:`logs/<app>/<yyyy-MM>/<yyyy-MM-dd>/`
|
||
- `info.log`:记录 `INFO/WARN`
|
||
- `error.log`:记录 `ERROR` 及以上
|
||
- 请求链路字段:`traceId`(来自 `X-Request-Id`/`X-Trace-Id`)
|
||
- 如果服务部署在网关后,请务必配置 `TRUSTED_PROXIES` 为网关出口网段,否则会记录到网关 IP。
|
||
|
||
## 健康检查
|
||
|
||
- `GET /health`
|
||
- `GET /health/live`
|
||
- `GET /health/ready`(含当前会话统计)
|
||
- `GET /health/lsp-status`(按语言的 LSP 在线探测状态)
|
||
|
||
## HTTP 补全接口
|
||
|
||
- `POST /api/v1/completions/:language`
|
||
|
||
示例(JavaScript):
|
||
|
||
```json
|
||
{
|
||
"sessionId": "editor-1",
|
||
"language": "javascript",
|
||
"uri": "file:///main.js",
|
||
"text": "const a = console.lo",
|
||
"line": 0,
|
||
"character": 20
|
||
}
|
||
```
|
||
|
||
## WebSocket 接口
|
||
|
||
- `GET /ws/completions`
|
||
- `GET /ws/completions/:language`
|
||
|
||
支持两种消息格式:
|
||
|
||
1) 简化消息:
|
||
|
||
```json
|
||
{
|
||
"id": "1",
|
||
"sessionId": "editor-1",
|
||
"language": "go",
|
||
"uri": "file:///main.go",
|
||
"text": "package main\n\nimport \"fmt\"\n\nfunc main() {\n\tfmt.Pri\n}",
|
||
"line": 5,
|
||
"character": 9
|
||
}
|
||
```
|
||
|
||
2) JSON-RPC 风格:
|
||
|
||
```json
|
||
{
|
||
"jsonrpc": "2.0",
|
||
"id": 1,
|
||
"method": "completion/complete",
|
||
"params": {
|
||
"sessionId": "editor-1",
|
||
"language": "typescript",
|
||
"uri": "file:///main.ts",
|
||
"text": "console.lo",
|
||
"line": 0,
|
||
"character": 10
|
||
}
|
||
}
|
||
```
|
||
|
||
## 备注
|
||
|
||
- `line` / `character` 为 0-based。
|
||
- `uri` 支持 `file:///main.go` 这类相对根路径,网关会映射到 `WORKSPACE_DIR` 下。
|
||
- 前端建议稳定传 `sessionId`,避免频繁新建语言服务器进程。
|
||
- 多实例场景下,如果请求落到非会话所属实例,服务会返回 `409` 并携带 `routeTo` 与 `X-LSP-Route-To`。
|