mu-dispatcher是mu.semte.ch架构中的核心元素之一。该服务根据传入请求的路径将请求分发到其他微服务。您可以通过Docker运行该服务,但通常建议使用http://github.com/mu-semtech/mu-project%E8%BF%9B%E8%A1%8C%E9%85%8D%E7%BD%AE%EF%BC%8C%E4%BB%A5%E5%BA%94%E7%94%A8%E8%87%AA%E5%AE%9A%E4%B9%89%E8%AE%BE%E7%BD%AE%E3%80%82
Dispatcher作为一个应用运行,其中Dispatcher模块可被覆盖。启动时,它期望在/config/dispatcher.ex路径下存在dispatcher.ex文件。
Dispatcher通过https://github.com/mu-semtech/mu-project%E4%B8%AD%E7%9A%84dispatcher.ex%E6%96%87%E4%BB%B6%E8%BF%9B%E8%A1%8C%E9%85%8D%E7%BD%AE%E3%80%82
基本(默认)配置是一个名为Dispatcher的Elixir模块,它使用Matcher功能。需要定义空的接受类型集(define_accept_types [])。
elixirdefmodule Dispatcher do use Matcher define_accept_types [] ... end
使用Matcher
use Matcher宏用于设置匹配器,它会导入Matcher、send_resp和forward函数。
HTTP方法
支持以下HTTP方法宏:get、put、post、delete、patch、head、options、match。其中match宏匹配所有方法。
参数:
path:字符串,可包含变量解构options:选项哈希,包含匹配条件:
accept:通过define_accept_types定义的接受类型简写last_call:设为true时用于fallback路由(如404页面)block:处理和发送请求的代码块提供变量:
conn:Plug连接对象,用于转发或响应path:当路径定义为"/something/*path"时,包含未使用的路径段define_accept_types
提供一种将Accept类型映射到可读术语的方式,便于一致匹配。接收一个属性数组,描述每个使用的键及其对应的Accept头,支持通配符。
可将一个路径代理到另一个路径。例如,将/sessions请求转发到http://sessionsservice/login:
elixirdefmodule Dispatcher do use Matcher define_accept_types [] match "/sessions", _ do forward conn, [], "http://sessionsservice/login" end end
可在代码块中添加额外逻辑,如日志记录:
elixirdefmodule Dispatcher do use Matcher define_accept_types [] match "/sessions", _ do IO.inspect(conn, label: "conn for /sessions") forward conn, [], "http://sessionsservice/login" end end
转发子路由,例如将所有/widgets开头的请求转发到mu-cl-resources服务:
elixirdefmodule Dispatcher do use Matcher define_accept_types [] match "/widgets/*path", _ do forward conn, path, "http://resource/widgets" end end
可显式匹配HTTP方法。例如,仅转发POST请求:
elixirdefmodule Dispatcher do use Matcher define_accept_types [] post "/sessions", _ do forward conn, [], "http://sessionsservice/login" end end
支持基于主机名的分发,支持字符串格式、数组格式和通配符。
匹配特定主机:
elixirget "/employees", %{ host: "api.redpencil.io" } do ... end
通配符匹配:
elixirget "/employees", %{ host: "*.redpencil.io" } do ... end
提取子域名:
elixirget "/employees", %{ host: ["io", "redpencil", subdomain | subsubdomains] } do IO.inspect(subdomain, "First subdomain") IO.inspect(subsubdomains, "Array of subdomains under subdomain") ... end
根据客户端请求的MIME类型分发请求。首先通过define_accept_types定义Accept类型简写:
elixirdefmodule Dispatcher do use Matcher define_accept_types [ json: ["application/json", "application/vnd.api+json"], img: ["image/jpg", "image/jpeg", "image/png"], gif: ["image/gif"] ] get "/images/*path", %{ accept: %{ json: true } } do forward conn, path, "http://resource/images" end get "/images/*path", %{ accept: %{ img: true } } do forward conn, path, "http://images/images" end get "/images/*path", %{ accept: %{ gif: true } } do forward conn, path, "http://gifs/images" end end
当没有匹配的路由时,应提供404响应。使用last_call: true选项配置fallback路由:
elixirdefmodule Dispatcher do use Matcher define_accept_types [ text: ["text/*"], html: ["text/html", "application/xhtml+html"], json: ["application/json", "application/vnd.api+json"], img: ["image/jpg", "image/jpeg", "image/png"], gif: ["image/gif"], image: ["image/*"] ] # 其他路由规则... get "/*_", %{ last_call: true, accept: %{ json: true } } do send_resp(conn, 404, "{ \"error\": { \"code\": 404, \"message\": \"Route not found. See config/dispatcher.ex\" } }") end get "/*_", %{ last_call: true, accept: %{ image: true } } do forward conn, [], "http://images/404" end get "/*_", %{ last_call: true, accept: %{ text: true } } do send_resp(conn, 404, "404 - page not found\n\nSee config/dispatcher.ex") end get "/*_", %{ last_call: true, accept: %{ html: true } } do send_resp(conn, 404, "<html><head><title>404 - Not Found</title></head><body><h1>404 - Page not found</h1></body></html>") end end
可在转发前添加逻辑,如复用配置、日志记录或请求修改:
elixirdefmodule Dispatcher do use Matcher define_accept_types [ json: ["application/json", "application/vnd.api+json"] ] @json %{ accept: %{ json: true } } match "/sessions/*path", @json do IO.inspect(conn, label: "Connection for sessions service.") forward conn, path, "http://sessions/login" end match "/images/*path", @json do forward conn, path, "http://resource/images" end match "/*_", %{ last_call: true, accept: %{ json: true } } do send_resp(conn, 404, "{ \"error\": { \"code\": 404, \"message\": \"Route not found. See config/dispatcher.ex\" } }") end end
配置Ember应用路由,优先提供HTML页面,同时处理资产请求:
elixirdefmodule Dispatcher do use Matcher define_accept_types [ json: ["application/json", "application/vnd.api+json"], html: ["text/html", "application/xhtml+html"], any: ["*/*"] ] @html %{ accept: %{ html: true } } @json %{ accept: %{ json: true } } @any %{ accept: %{ any: true } } # 其他路由规则... match "/assets/*path", @any do forward conn, path, "http://frontend/assets/" end match "/*_path", @html do forward conn, [], "http://frontend/index.html" end match "/*_", %{ last_call: true, accept: %{ json: true } } do send_resp(conn, 404, "{ \"error\": { \"code\": 404, \"message\": \"Route not found. See config/dispatcher.ex\" } }") end end
处理跨域请求的OPTIONS预检请求:
elixirdefmodule Dispatcher do use Matcher define_accept_types [] options "*path", _ do conn |> Plug.Conn.put_resp_header("access-control-allow-headers", "content-type,accept") |> Plug.Conn.put_resp_header("access-control-allow-methods", "*") |> send_resp(200, "{ \"message\": \"ok\" }") end end
为不同Accept类型提供404响应:
elixirdefmodule Dispatcher do use Matcher define_accept_types [ text: ["text/*"], html: ["text/html", "application/xhtml+html"], json: ["application/json", "application/vnd.api+json"], jpeg: ["image/jpg", "image/jpeg"], png: ["image/png"], gif: ["image/gif"], ] # 其他路由规则... get "/*_", %{ last_call: true, accept: %{ json: true } } do send_resp(conn, 404, "{ \"error\": { \"code\": 404, \"message\": \"Route not found. See config/dispatcher.ex\" } }") end get "/*_", %{ last_call: true, accept: %{ text: true } } do send_resp(conn, 404, "404 - page not found\n\nSee config/dispatcher.ex") end get "/*_", %{ last_call: true, accept: %{ html: true } } do send_resp(conn, 404, "<html><head><title>404 - Not Found</title></head><body><h1>404 - Page not found</h1></body></html>") end get "/*_", %{ last_call: true, accept: %{ jpeg: true } } do forward conn, [], "http://static/404.jpeg" end get "/*_", %{ last_call: true, accept: %{ png: true } } do forward conn, [], "http://static/404.png" end get "/*_", %{ last_call: true, accept: %{ gif: true } } do forward conn, [], "http://static/404.gif" end end
转发功能基于plug_mint_proxy构建,使用Mint库创建高效请求。请求接收基于Cowboy 2,支持HTTP/2。
https://github.com/elixir-plug/plug%E9%80%9A%E8%BF%87%E8%87%AA%E8%BA%AB%E7%9A%84%E5%8C%B9%E9%85%8D%E5%99%A8%E5%92%8C%E5%88%86%E5%8F%91%E5%99%A8%E5%8C%B9%E9%85%8D%E8%B0%83%E7%94%A8%E3%80%82%E6%9C%AC%E5%BA%93%E5%9C%A8plug_router_dispatcher.ex%E4%B8%AD%E6%8F%90%E4%BE%9B%E4%BA%86%E9%A2%9D%E5%A4%96%E6%94%AF%E6%8C%81%EF%BC%8C%E5%B0%86%E8%AF%B7%E6%B1%82%E5%88%86%E5%8F%91%E5%88%B0%E8%87%AA%E5%AE%9A%E4%B9%89%E5%8C%B9%E9%85%8D%E5%99%A8%E3%80%82
Dispatcher支持以下头部操作,通过plug_mint_proxy的操作器配置:
Matcher模块包含核心逻辑,解析请求Accept头和定义的接受类型,寻找最佳分发方案。分发流程如下:
define_accept_types中定义的类型匹配(支持通配符),得到(B)last_call: true选项寻找fallback路由您可以使用以下命令拉取该镜像。请将 <标签> 替换为具体的标签版本。如需查看所有可用标签版本,请访问 标签列表页面。


探索更多轩辕镜像的使用方法,找到最适合您系统的配置方式
通过 Docker 登录认证访问私有仓库
无需登录使用专属域名
Kubernetes 集群配置 Containerd
K3s 轻量级 Kubernetes 镜像加速
VS Code Dev Containers 配置
Podman 容器引擎配置
HPC 科学计算容器配置
ghcr、Quay、nvcr 等镜像仓库
Harbor Proxy Repository 对接专属域名
Portainer Registries 加速拉取
Nexus3 Docker Proxy 内网缓存
需要其他帮助?请查看我们的 常见问题Docker 镜像访问常见问题解答 或 提交工单
docker search 限制
站内搜不到镜像
离线 save/load
插件要用 plugin install
WSL 拉取慢
安全与 digest
新手拉取配置
镜像合规机制
manifest unknown
no matching manifest(架构)
invalid tar header(解压)
TLS 证书失败
DNS 超时
域名连通性排查
410 Gone 排查
402 与流量用尽
401 认证失败
429 限流
D-Bus 凭证提示
413 与超大单层
来自真实用户的反馈,见证轩辕镜像的优质服务