中间件组件规格
可注入 Dapr 处理管道的所有受支持的中间件组件列表。
下表列出了 Dapr 支持的中间件组件。了解如何自定义处理管道和设置中间件组件。
Table headers to note:
| Header | Description | Example |
|---|
| Status | Component certification status | Alpha Beta Stable
|
| Component version | The version of the component | v1 |
| Since runtime version | The version of the Dapr runtime when the component status was set or updated | 1.11 |
HTTP
1 - Bearer
使用 bearer 中间件通过验证 bearer 令牌来保护 HTTP 端点
bearer HTTP 中间件 在 Web API 上使用 OpenID Connect 验证 Bearer 令牌,而无需修改应用程序。此设计将身份验证/授权关注点与应用程序分离,使应用程序操作员能够采用和配置身份验证/授权提供程序,而不会影响应用程序代码。
组件格式
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: bearer-token
spec:
type: middleware.http.bearer
version: v1
metadata:
- name: audience
value: "<your token audience; i.e. the application's client ID>"
- name: issuer
value: "<your token issuer, e.g. 'https://accounts.google.com'>"
# Optional values
- name: jwksURL
value: "<JWKS URL, e.g. 'https://accounts.google.com/.well-known/openid-configuration'>"
规格元数据字段
| 字段 | 必填 | 详情 | 示例 |
|---|
audience | Y | 令牌中期望的受众。通常,这对应于在 OpenID Connect 平台托管的凭据下创建的应用程序的客户端 ID。 | |
issuer | Y | 颁发者机构,即令牌中颁发者声明的期望值。 | "https://accounts.google.com" |
jwksURL | N | JWKS(包含用于验证令牌的公钥的 JWK 集)的地址。如果为空,将尝试从 OpenID 配置文档 <issuer>/.well-known/openid-configuration 中获取 URL。 | "https://accounts.google.com/.well-known/openid-configuration" |
issuer 的常见值包括:
- Auth0:
https://{domain},其中 {domain} 是您的 Auth0 应用程序的域 - Microsoft Entra ID:
https://login.microsoftonline.com/{tenant}/v2.0,其中 {tenant} 应替换为您应用程序的租户 ID,格式为 UUID - Google:
https://accounts.google.com - Salesforce (Force.com):
https://login.salesforce.com
Dapr 配置
要应用中间件,必须在 配置 中引用该中间件。请参阅中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: bearer-token
type: middleware.http.bearer
相关链接
2 - OAuth2
使用 OAuth2 中间件来保护 HTTP 端点
OAuth2 HTTP 中间件 可在无需修改应用程序的情况下,为 Web API 启用 OAuth2 授权码流程。这种设计将身份验证/授权的关注点与应用程序分离,使应用程序运维人员可以采用和配置身份验证/授权提供程序,而不会影响应用程序代码。
组件格式
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: oauth2
spec:
type: middleware.http.oauth2
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "https://www.googleapis.com/auth/userinfo.email"
- name: authURL
value: "https://accounts.google.com/o/oauth2/v2/auth"
- name: tokenURL
value: "https://accounts.google.com/o/oauth2/token"
- name: redirectURL
value: "http://dummy.com"
- name: authHeaderName
value: "authorization"
- name: forceHTTPS
value: "false"
- name: pathFilter
value: ".*/users/.*"
警告
上述示例将密钥作为纯字符串使用。建议使用密钥存储来管理密钥,如
这里所述。
规范元数据字段
| 字段 | 详细信息 | 示例 |
|---|
| clientId | 您的应用程序的客户端 ID,它是作为由支持 OAuth 的平台托管的凭据的一部分创建的 | |
| clientSecret | 您的应用程序的客户端密钥,它是作为由支持 OAuth 的平台托管的凭据的一部分创建的 | |
| scopes | 以空格分隔、区分大小写的 scope 字符串列表,通常用于应用程序中的授权 | "https://www.googleapis.com/auth/userinfo.email" |
| authURL | OAuth2 授权服务器的端点 | "https://accounts.google.com/o/oauth2/v2/auth" |
| tokenURL | 客户端用于通过出示其授权授权或刷新令牌来获取访问令牌的端点 | "https://accounts.google.com/o/oauth2/token" |
| redirectURL | 授权服务器应在用户完成身份验证后重定向到的 Web 应用程序 URL | "https://myapp.com" |
| authHeaderName | 要转发到您的应用程序的授权标头名称 | "authorization" |
| forceHTTPS | 如果为 true,则强制使用 TLS/SSL | "true","false" |
| pathFilter | 仅将中间件应用于与给定路径模式匹配的请求 | ".*/users/.*" |
Dapr 配置
要应用中间件,必须在配置中引用它。请参阅中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: oauth2
type: middleware.http.oauth2
请求路径过滤
pathFilter 字段允许您使用正则表达式模式根据 HTTP 请求路径有选择地应用 OAuth2 身份验证。这支持以下场景:例如为不同的 API 端点配置具有不同 scope 的多个 OAuth2 中间件,通过确保用户仅获得其预期操作所需的最小权限,来实现最小权限原则。
示例:分离只读和管理员用户访问
在以下配置中:
- 对
/api/users/* 端点的请求获得具有只读用户 scope 的令牌 - 对
/api/admin/* 端点的请求获得具有完整管理员 scope 的令牌
这通过防止不必要的权限访问并限制受损令牌的影响范围来降低安全风险。
# 具有只读访问权限的用户
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: oauth2-users
spec:
type: middleware.http.oauth2
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "user:read profile:read"
- name: authURL
value: "https://accounts.google.com/o/oauth2/v2/auth"
- name: tokenURL
value: "https://accounts.google.com/o/oauth2/token"
- name: redirectURL
value: "http://myapp.com/callback"
- name: pathFilter
value: "^/api/users/.*"
---
# 具有完整管理员访问权限的用户
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: oauth2-admin
spec:
type: middleware.http.oauth2
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "admin:read admin:write user:read user:write"
- name: authURL
value: "https://accounts.google.com/o/oauth2/v2/auth"
- name: tokenURL
value: "https://accounts.google.com/o/oauth2/token"
- name: redirectURL
value: "http://myapp.com/callback"
- name: pathFilter
value: "^/api/admin/.*"
相关链接
3 - OAuth2 客户端凭据
使用 OAuth2 客户端凭据中间件保护 HTTP 端点
OAuth2 客户端凭据 HTTP 中间件 可在无需修改应用程序的情况下,为 Web API 启用 OAuth2 客户端凭据流。这种设计将身份验证/授权的关注点与应用程序分离,使得应用程序运维人员可以采用和配置身份验证/授权提供方,而不会影响应用程序代码。
组件格式
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: oauth2clientcredentials
spec:
type: middleware.http.oauth2clientcredentials
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "https://www.googleapis.com/auth/userinfo.email"
- name: tokenURL
value: "https://accounts.google.com/o/oauth2/token"
- name: headerName
value: "authorization"
- name: pathFilter
value: ".*/users/.*"
警告
上述示例将密钥作为纯字符串使用。建议按照
此处的说明使用密钥存储来管理密钥。
规范元数据字段
| 字段 | 详情 | 示例 |
|---|
| clientId | 在支持 OAuth 的平台上托管作为凭据的一部分而创建的应用程序客户端 ID | |
| clientSecret | 在支持 OAuth 的平台上托管作为凭据的一部分而创建的应用程序客户端密钥 | |
| scopes | 以空格分隔的、区分大小写的范围字符串列表,通常用于应用程序中的授权 | "https://www.googleapis.com/auth/userinfo.email" |
| tokenURL | 客户端通过呈现其授权授予或刷新令牌来获取访问令牌的端点 | "https://accounts.google.com/o/oauth2/token" |
| headerName | 转发到应用程序的授权标头名称 | "authorization" |
| endpointParamsQuery | 指定对令牌端点的请求的附加参数 | true |
| authStyle | 可选地指定端点希望如何发送客户端 ID 和客户端密钥。请参阅下表中的可能值 | 0 |
| pathFilter | 仅将中间件应用于匹配给定路径模式的请求 | ".*/users/.*" |
authStyle 的可能值
| 值 | 含义 |
|---|
1 | 在 POST 正文 中发送 “client_id” 和 “client_secret” 作为 application/x-www-form-urlencoded 参数。 |
2 | 使用 HTTP 基本认证 发送 “client_id” 和 “client_secret”。这是 OAuth2 RFC 6749 第 2.3.1 节中描述的一种可选样式。 |
0 | 表示通过尝试两种方式并缓存成功的方式来自动检测提供方想要的认证样式。 |
Dapr 配置
要应用中间件,必须在配置中引用该中间件。请参阅中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: oauth2clientcredentials
type: middleware.http.oauth2clientcredentials
请求路径过滤
pathFilter 字段允许您使用正则表达式模式,基于 HTTP 请求路径有选择地应用 OAuth2 身份验证。这支持诸如配置多个具有不同范围的 OAuth2 中间件用于不同 API 端点、通过确保用户仅获得其预期操作所需的最小权限来实现最小权限原则等场景。
示例:区分只读用户和管理员用户访问
在以下配置中:
- 对
/api/users/* 端点的请求接收带有只读用户范围的令牌 - 对
/api/admin/* 端点的请求接收带有完整管理员范围的令牌
这通过防止不必要的特权访问和限制受损令牌的影响范围来降低安全风险。
# 具有只读访问范围的用户
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: oauth2clientcredentials-users
spec:
type: middleware.http.oauth2clientcredentials
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "user:read profile:read"
- name: tokenURL
value: "https://accounts.google.com/o/oauth2/token"
- name: headerName
value: "authorization"
- name: pathFilter
value: "^/api/users/.*"
---
# 具有完整管理员访问范围的用户
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: oauth2clientcredentials-admin
spec:
type: middleware.http.oauth2clientcredentials
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "admin:read admin:write user:read user:write"
- name: tokenURL
value: "https://accounts.google.com/o/oauth2/token"
- name: headerName
value: "authorization"
- name: pathFilter
value: "^/api/admin/.*"
相关链接
4 - 应用 Open Policy Agent (OPA) 策略
使用中间件对传入请求应用 Open Policy Agent (OPA) 策略
Open Policy Agent (OPA) HTTP 中间件将 OPA 策略应用于传入的 Dapr HTTP 请求。这可用于对应用端点应用可重用的授权策略。
组件格式
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: my-policy
spec:
type: middleware.http.opa
version: v1
metadata:
# `includedHeaders` 是以逗号分隔的、不区分大小写的请求头集合,
# 这些请求头将被包含在请求输入中。
# 默认情况下,请求头不会传递给策略。若要在输入中接收传入请求头,
# 请包含此配置
- name: includedHeaders
value: "x-my-custom-header, x-jwt-header"
# `defaultStatus` 是拒绝响应时返回的状态码
- name: defaultStatus
value: 403
# `readBody` 控制中间件是否在内存中读取完整的请求体,
# 以便用于策略决策。
- name: readBody
value: "false"
# `rego` 是要评估的 open policy agent 策略。必填
# 策略包必须是 http,且策略必须设置 data.http.allow
- name: rego
value: |
package http
default allow = true
# Allow 也可以是一个对象,并包含其他属性
# 例如,如果你想在策略失败时重定向,可以设置状态码为 301,
# 并在响应上设置 location 请求头:
allow = {
"status_code": 301,
"additional_headers": {
"location": "https://my.site/authorize"
}
} {
not jwt.payload["my-claim"]
}
# 你也可以允许请求并为其添加额外的请求头:
allow = {
"allow": true,
"additional_headers": {
"x-my-claim": my_claim
}
} {
my_claim := jwt.payload["my-claim"]
}
jwt = { "payload": payload } {
auth_header := input.request.headers["Authorization"]
[_, jwt] := split(auth_header, " ")
[_, payload, _] := io.jwt.decode(jwt)
}
你可以使用 官方 OPA playground 原型和实验策略。例如,可以在这里找到上述示例策略。
规范元数据字段
| 字段 | 详情 | 示例 |
|---|
rego | Rego 策略语言 | 见上文 |
defaultStatus | 拒绝响应时返回的状态码 | "403" |
readBody | 如果设置为 true(默认值),则会完整读取每个请求的请求体到内存中,并可用于策略决策。如果你的策略不依赖于检查请求体,考虑将其禁用(设置为 false)以获得显著的性能提升。 | "false" |
includedHeaders | 以逗号分隔的、不区分大小写的请求头集合,这些请求头将被包含在请求输入中。默认情况下,请求头不会传递给策略。若要在输入中接收传入请求头,请包含此配置 | "x-my-custom-header, x-jwt-header" |
Dapr 配置
要应用中间件,必须在 配置中引用它。请参阅中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: my-policy
type: middleware.http.opa
输入
此中间件提供 HTTPRequest 作为输入。
HTTPRequest
HTTPRequest 输入包含关于传入 HTTP 请求的所有相关信息。
type Input struct {
request HTTPRequest
}
type HTTPRequest struct {
// 请求方法(例如 GET、POST 等...)
method string
// 原始请求路径(例如 "/v2/my-path/")
path string
// 将路径分解为多个部分以便于使用(例如 ["v2", "my-path"])
path_parts string[]
// 原始查询字符串(例如 "?a=1&b=2")
raw_query string
// 将查询分解为键及其值
query map[string][]string
// 请求头
// 注意:默认情况下,不包含任何请求头。你必须通过
// `spec.metadata.includedHeaders` 指定想要接收的请求头(见上文)
headers map[string]string
// 请求方案(例如 http、https)
scheme string
// 请求体(例如 http、https)
body string
}
结果
策略必须设置 data.http.allow,其值为 boolean 类型,或带有 allow 布尔属性的 object 类型。allow 为 true 将允许请求,而 false 值将拒绝请求,并返回由 defaultStatus 指定的状态码。以下策略使用默认值,演示了对所有请求返回 403 - Forbidden:
package http
default allow = false
这等同于:
package http
default allow = {
"allow": false
}
更改拒绝响应的状态码
拒绝请求时,你可以覆盖返回的状态码。例如,如果你想返回 401 而不是 403,可以执行以下操作:
package http
default allow = {
"allow": false,
"status_code": 401
}
添加响应头
要重定向,请添加请求头并将 status_code 设置为返回结果:
package http
default allow = {
"allow": false,
"status_code": 301,
"additional_headers": {
"Location": "https://my.redirect.site"
}
}
添加请求头
你还可以在允许的请求上设置额外的请求头:
package http
default allow = false
allow = { "allow": true, "additional_headers": { "X-JWT-Payload": payload } } {
not input.path[0] == "forbidden"
// 其中 `jwt` 是另一个规则的结果
payload := base64.encode(json.marshal(jwt.payload))
}
结果结构
type Result bool
// 或
type Result struct {
// 是否允许或拒绝传入请求
allow bool
// 覆盖拒绝响应的状态码;可选
status_code int
// 在允许的请求或拒绝响应上设置请求头;可选
additional_headers map[string]string
}
相关链接
5 - Router alias http request routing
使用 router alias 中间件将任意 HTTP 路由别名为 Dapr 端点
Router alias HTTP 中间件组件允许您将传入 Dapr 的任意 HTTP 路由转换为有效的 Dapr API 端点。
组件格式
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: routeralias
spec:
type: middleware.http.routeralias
version: v1
metadata:
# String containing a JSON-encoded or YAML-encoded dictionary
# Each key in the dictionary is the incoming path, and the value is the path it's converted to
- name: "routes"
value: |
{
"/mall/activity/info": "/v1.0/invoke/srv.default/method/mall/activity/info",
"/hello/activity/{id}/info": "/v1.0/invoke/srv.default/method/hello/activity/info",
"/hello/activity/{id}/user": "/v1.0/invoke/srv.default/method/hello/activity/user"
}
在上面的示例中,传入的 HTTP 请求 /mall/activity/info?id=123 会被转换为 /v1.0/invoke/srv.default/method/mall/activity/info?id=123。
规范元数据字段
| 字段 | 详情 | 示例 |
|---|
routes | 包含 JSON 编码或 YAML 编码字典的字符串。字典中的每个键是传入路径,值是其要转换到的路径。 | 见上面的示例 |
Dapr 配置
要应用中间件,必须在配置中引用它。请参阅中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: routeralias
type: middleware.http.routeralias
相关链接
6 - RouterChecker HTTP 请求路由
使用 routerchecker 中间件阻止无效的 HTTP 请求路由
RouterChecker HTTP [中间件](https://docs.dapr.io/zh-hans/operations/components/middleware/)组件利用正则表达式来检查 HTTP 请求路由的有效性,防止无效路由进入 Dapr 集群。RouterChecker 组件会过滤掉错误请求,从而减少遥测和日志数据中的噪音。
组件格式
RouterChecker 将一组规则应用于传入的 HTTP 请求。你可以使用正则表达式在组件元数据中定义这些规则。在以下示例中,HTTP 请求 RouterChecker 被设置为根据 ^[A-Za-z0-9/._-]+$ 正则表达式验证所有请求消息。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: routerchecker
spec:
type: middleware.http.routerchecker
version: v1
metadata:
- name: rule
value: "^[A-Za-z0-9/._-]+$"
在此示例中,上述定义将产生以下通过/失败案例:
PASS /v1.0/invoke/demo/method/method
PASS /v1.0/invoke/demo.default/method/method
PASS /v1.0/invoke/demo.default/method/01
PASS /v1.0/invoke/demo.default/method/METHOD
PASS /v1.0/invoke/demo.default/method/user/info
PASS /v1.0/invoke/demo.default/method/user_info
PASS /v1.0/invoke/demo.default/method/user-info
FAIL /v1.0/invoke/demo.default/method/cat password
FAIL /v1.0/invoke/demo.default/method/" AND 4210=4210 limit 1
FAIL /v1.0/invoke/demo.default/method/"$(curl
规范元数据字段
| 字段 | 详情 | 示例 |
|---|
| rule | HTTP 请求 RouterChecker 使用的正则表达式 | ^[A-Za-z0-9/._-]+$ |
Dapr 配置
要应用该中间件,必须在[配置](https://docs.dapr.io/zh-hans/concepts/configuration-concept/)中引用它。请参阅[中间件管道](https://docs.dapr.io/zh-hans/operations/components/middleware/#customize-processing-pipeline)。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: routerchecker
type: middleware.http.routerchecker
相关链接
7 - Sentinel 容错中间件组件
使用 Sentinel 中间件来保障应用的可靠性和弹性
Sentinel 是一个强大的容错组件,以"流量"为切入点,涵盖了流量控制、流量整形、并发限制、熔断降级和自适应系统保护等多个领域,从而保障微服务的可靠性和弹性。
Sentinel HTTP 中间件 使 Dapr 能够利用 Sentinel 的强大能力来保护你的应用程序。有关 Sentinel 的更多细节,你可以参考 Sentinel Wiki。
组件格式
在以下定义中,每秒最大请求数设置为 10:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: sentinel
spec:
type: middleware.http.sentinel
version: v1
metadata:
- name: appName
value: "nodeapp"
- name: logDir
value: "/var/tmp"
- name: flowRules
value: >-
[
{
"resource": "POST:/v1.0/invoke/nodeapp/method/neworder",
"threshold": 10,
"tokenCalculateStrategy": 0,
"controlBehavior": 0
}
]
规格元数据字段
| 字段 | 详情 | 示例 |
|---|
| appName | 当前运行服务的名称 | nodeapp |
| logDir | 日志目录路径 | /var/tmp/sentinel |
| flowRules | Sentinel 流量控制规则的 JSON 数组 | 流量控制规则 |
| circuitBreakerRules | Sentinel 熔断规则的 JSON 数组 | 熔断规则 |
| hotSpotParamRules | Sentinel 热点参数流量控制规则的 JSON 数组 | 热点规则 |
| isolationRules | Sentinel 隔离规则的 JSON 数组 | 隔离规则 |
| systemRules | Sentinel 系统规则的 JSON 数组 | 系统规则 |
一旦达到限制,请求将返回 HTTP 状态码 429:请求过多。
每个规则定义中的 resource 字段需特别注意。在 Dapr 中,它遵循以下格式:
POST/GET/PUT/DELETE:Dapr HTTP API 请求路径
所有具体的 HTTP API 信息可以在 Dapr API 参考 中找到。在上述示例配置中,resource 字段设置为 POST:/v1.0/invoke/nodeapp/method/neworder。
Dapr 配置
要使中间件生效,必须在 配置 中引用该中间件。请参阅 中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprConfig
spec:
httpPipeline:
handlers:
- name: sentinel
type: middleware.http.sentinel
相关链接
8 - 将请求体转换为大写
使用 uppercase 中间件测试您的 HTTP 管道是否正常工作
uppercase HTTP 中间件 将请求体转换为大写字母,用于测试管道是否正常工作。它仅应用于本地开发。
组件格式
在以下定义中,它将请求体的内容转换为大写:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: uppercase
spec:
type: middleware.http.uppercase
version: v1
此组件没有需要配置的 metadata。
Dapr 配置
要应用中间件,必须在配置中引用它。请参阅中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: uppercase
type: middleware.http.uppercase
相关链接
9 - Wasm
在 HTTP 管道中使用 Wasm 中间件
WebAssembly 是一种安全执行跨语言编译代码的机制。运行时负责加载并运行 WebAssembly 模块(Wasm),这些模块通常以 .wasm 为扩展名的二进制文件形式存在。
通过 Wasm HTTP 中间件,你可以使用自定义逻辑处理传入请求或构造响应,这些逻辑会被编译成 Wasm 二进制文件。换句话说,你可以使用外部文件扩展 Dapr,而无需将代码预编译到 daprd 二进制文件中。Dapr 内嵌了 wazero 来实现这一能力,且无需 CGO 依赖。
Wasm 二进制文件通过 URL 加载。例如,file://rewrite.wasm 会从进程当前目录加载 rewrite.wasm。在 Kubernetes 环境中,请参考如何:将 Pod 卷挂载到 Dapr 边车来配置包含 Wasm 模块的文件系统挂载。
也支持从远程 URL 获取 Wasm 二进制文件。这种情况下,URL 必须严格指向单个 Wasm 二进制文件。例如:
http://example.com/rewrite.wasm,或https://example.com/rewrite.wasm。
组件格式
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: wasm
spec:
type: middleware.http.wasm
version: v1
metadata:
- name: url
value: "file://router.wasm"
- name: guestConfig
value: {"environment":"production"}
规格元数据字段
用户至少需要提供一个实现 http-handler 接口的 Wasm 二进制文件。具体编译方法将在后续说明。
| 字段 | 说明 | 是否必填 | 示例 |
|---|
| url | 用于实例化的 Wasm 二进制资源 URL。支持的协议方案包括 file://、http:// 和 https://。file:// URL 的路径是相对于 Dapr 进程的,除非以 / 开头表示绝对路径。 | 是 | file://hello.wasm, https://example.com/hello.wasm |
| guestConfig | 传递给 Wasm 客户端的可选配置。用户可以传入任意字符串,由客户端代码自行解析。 | 否 | environment=production,{"environment":"production"} |
Dapr 配置
要使中间件生效,必须在 configuration 中引用它。请参阅中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: wasm
type: middleware.http.wasm
注意:与原生中间件相比,WebAssembly 中间件会消耗更多资源。这会导致资源约束比原生代码实现的相同逻辑更快出现。生产环境使用时应该控制最大并发。
生成 Wasm
此组件允许你使用自定义逻辑处理传入请求或生成响应,这些逻辑通过 http-handler 应用二进制接口(ABI)编译而成。handle_request 函数接收传入请求,可以根据需要操作该请求或生成响应。
要编译 Wasm,必须使用符合 http-handler 规范的客户端 SDK,例如 TinyGo。
以下是一个 TinyGo 示例:
package main
import (
"strings"
"github.com/http-wasm/http-wasm-guest-tinygo/handler"
"github.com/http-wasm/http-wasm-guest-tinygo/handler/api"
)
func main() {
handler.HandleRequestFn = handleRequest
}
// handleRequest 实现了一个简单的 HTTP 路由器。
func handleRequest(req api.Request, resp api.Response) (next bool, reqCtx uint32) {
// 如果 URI 以 /host 开头,则去掉该前缀并分发给下一个处理器。
if uri := req.GetURI(); strings.HasPrefix(uri, "/host") {
req.SetURI(uri[5:])
next = true // 继续执行宿主机上的下一个处理器。
return
}
// 返回静态响应
resp.Headers().Set("Content-Type", "text/plain")
resp.Body().WriteString("hello")
return // 跳过下一个处理器,因为我们已经写入了响应。
}
如果使用 TinyGo,请按以下方式编译,并将 spec 元数据字段中的 url 设置为输出文件的位置(例如 file://router.wasm):
tinygo build -o router.wasm -scheduler=none --no-debug -target=wasi router.go`
Wasm guestConfig 示例
以下是如何使用 guestConfig 向 Wasm 传递配置的示例。在 Wasm 代码中,可以使用客户端 SDK 中定义的 handler.Host.GetConfig 函数来获取配置。在下面的示例中,Wasm 中间件解析了组件中定义的 JSON 配置里的 environment 字段。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: wasm
spec:
type: middleware.http.wasm
version: v1
metadata:
- name: url
value: "file://router.wasm"
- guestConfig
value: {"environment":"production"}
下面是 TinyGo 的示例:
package main
import (
"encoding/json"
"github.com/http-wasm/http-wasm-guest-tinygo/handler"
"github.com/http-wasm/http-wasm-guest-tinygo/handler/api"
)
type Config struct {
Environment string `json:"environment"`
}
func main() {
// 获取配置字节,即组件中定义的 guestConfig 值。
configBytes := handler.Host.GetConfig()
config := Config{}
json.Unmarshal(configBytes, &config)
handler.Host.Log(api.LogLevelInfo, "Config environment: "+config.Environment)
}
相关链接
10 - 速率限制
使用速率限制中间件来限制每秒请求数
速率限制 HTTP 中间件 允许限制每秒允许的最大 HTTP 请求数。速率限制可以保护您的应用程序免受拒绝服务(DoS)攻击。DoS 攻击可能由恶意的第三方发起,也可能由您软件中的错误引起(即"友军误伤"式 DoS 攻击)。
组件格式
在以下定义中,每秒最大请求数设置为 10:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: ratelimit
spec:
type: middleware.http.ratelimit
version: v1
metadata:
- name: maxRequestsPerSecond
value: 10
规范元数据字段
| 字段 | 详情 | 示例 |
|---|
maxRequestsPerSecond | 按远程 IP 计算的每秒最大请求数。 组件会查看 X-Forwarded-For 和 X-Real-IP 请求头来确定调用者的 IP。 | 10 |
一旦达到限制,请求将失败并返回 HTTP 状态码 429: Too Many Requests。
重要
速率限制在每个 Dapr 边车中独立执行,而不是集群范围的。或者,可以使用最大并发设置来对应用程序进行速率限制,该设置适用于所有流量,无论远程 IP、协议或路径如何。
Dapr 配置
要应用中间件,必须在配置中引用它。请参阅中间件管道。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
httpPipeline:
handlers:
- name: ratelimit
type: middleware.http.ratelimit
相关链接