微服务解决方案:添加新的应用程序
您必须拥有 ABP Business 或更高级别的许可证,才能创建微服务解决方案。
您可以将新的应用程序添加到微服务解决方案模板中。本文档解释了如何向解决方案中添加新的 Web 应用程序。在解决方案模板中,根目录下有一个名为 apps 的文件夹,其中包含解决方案中的所有应用程序。您可以出于不同目的创建单独的应用程序,例如 Web 应用程序、用于落地页的公共网站或管理面板。
此外,根目录下还有一个名为 _templates 的文件夹。此文件夹包含可用于创建新微服务、API 网关和应用程序的模板。这些模板可以根据您的需要进行定制。
添加新的 Web 应用程序
要向解决方案中添加新的 Web 应用程序,您可以使用 web 模板。此模板会创建一个带有必要配置和依赖项的新 ASP.NET Core 应用程序。请按照以下步骤添加新的 Web 应用程序:
在 ABP Studio 的 解决方案资源管理器 中,右键单击 apps 文件夹,然后选择 添加 -> 新建模块 -> Web。
这将打开 创建新模块 对话框。输入新应用程序的名称,如果需要则指定输出目录,然后单击 下一步 按钮。有一个命名约定:模块名称 应包含解决方案名称作为前缀,并且模块名称中不允许使用点 (.) 字符。
选择 UI 框架,然后单击 下一步 按钮。
选择 UI 主题,然后单击 创建 按钮。
新应用程序已创建并添加到解决方案中。您可以在 apps 文件夹中看到新应用程序。
配置 appsettings.json
新应用程序已创建了必要的配置和依赖项。我们应该配置 appsettings.json 文件,为身份验证设置 Authority 部分,为 API 网关设置 Gateway 部分。您可以从现有的 Web 应用程序复制配置,并根据新应用程序进行修改。以下是 Public Web 应用程序的 appsettings.json 文件示例。
{
"App": {
"SelfUrl": "http://localhost:44344",
"EnablePII": false
},
"AuthServer": {
"Authority": "http://localhost:44387",
"RequireHttpsMetadata": "false",
"ClientId": "WebPublic",
"ClientSecret": "1q2w3e*",
"IsOnK8s": "false",
"MetaAddress": "http://localhost:44387"
},
"RemoteServices": {
"Default": {
"BaseUrl": "http://localhost:44333"
}
},
...
}
配置 OpenId 选项
您可以使用现有的 OpenIddict 应用程序 或为新 Web 应用程序创建一个新的。在我们的示例中,我们使用 WebPublic 作为 ClientId,使用 1q2w3e* 作为 ClientSecret。根据 appsettings.json 文件中的配置,我们应该配置 Identity 服务中的 OpenIddictDataSeeder 类。您可以从现有的 Web 应用程序复制配置,并根据新应用程序进行修改。以下是 Public Web 应用程序的 OpenIddictDataSeeder 配置示例。
private async Task CreateClientsAsync()
{
...
//Web 公共客户端
var webPublicClientRootUrl = _configuration["OpenIddict:Applications:WebPublic:RootUrl"]!.EnsureEndsWith('/');
await CreateOrUpdateApplicationAsync(
name: "WebPublic",
type: OpenIddictConstants.ClientTypes.Confidential,
consentType: OpenIddictConstants.ConsentTypes.Implicit,
displayName: "Web 公共客户端",
secret: "1q2w3e*",
grantTypes: new List<string> //混合流程
{
OpenIddictConstants.GrantTypes.AuthorizationCode,
OpenIddictConstants.GrantTypes.Implicit
},
scopes: commonScopes.Union(new[]
{
"AuthServer",
"IdentityService",
"SaasService",
"AuditLoggingService",
"AdministrationService"
}).ToList(),
redirectUris: new List<string> { $"{webPublicClientRootUrl}signin-oidc" },
postLogoutRedirectUris: new List<string>() { $"{webPublicClientRootUrl}signout-callback-oidc" },
clientUri: webPublicClientRootUrl,
logoUri: "/images/clients/aspnetcore.svg"
);
}
将新应用程序的 URL 添加到 Identity 服务的 appsettings.json 文件中。
{
"OpenIddict": {
"Applications": {
...
"WebPublic": {
"RootUrl": "http://localhost:44344"
}
}
}
}
Prometheus 的 Docker 配置
如果您想在调试解决方案时使用 Prometheus 监控新应用程序,则应将新应用程序添加到 etc/docker/prometheus 文件夹中的 prometheus.yml 文件中。您可以从现有应用程序复制配置,并根据新应用程序进行修改。以下是 WebPublic 应用程序的 prometheus.yml 文件示例。
- job_name: 'webpublic'
scheme: http
metrics_path: 'metrics'
static_configs:
- targets: ['host.docker.internal:44344']
为新应用程序创建 Helm Chart
如果您想将新应用程序部署到 Kubernetes,您应该为新应用程序创建一个 Helm chart。
首先,将新应用程序添加到 etc/helm 文件夹中的 build-all-images.ps1 脚本中。您可以从现有应用程序复制配置,并根据新应用程序进行修改。以下是 WebPublic 应用程序的 build-all-images.ps1 脚本示例。
./build-image.ps1 -ProjectPath "../../apps/web-public/Acme.Bookstore.WebPublic/Acme.Bookstore.WebPublic.csproj" -ImageName bookstore/webpublic
由于我们希望在集群外部公开我们的应用程序,因此应将主机 URL 添加到 etc/helm/projectname 文件夹中的 values.projectname-local.yaml 文件中。以下是 WebPublic 应用程序的 values.bookstore-local.yaml 文件示例。
global:
...
hosts:
...
webpublic: "[RELEASE_NAME]-webpublic"
出于开发目的,我们还应该为新应用程序创建 TLS 证书。您可以编辑 etc/helm 文件夹中的 create-tls-certificate.ps1 脚本,为新应用程序生成 TLS 证书。以下是 WebPublic 应用程序的 create-tls-certificate.ps1 脚本示例。
mkcert --cert-file bookstore-local.pem --key-file bookstore-local-key.pem "bookstore-local" ... "bookstore-local-webpublic"
kubectl create namespace bookstore-local
kubectl create secret tls -n bookstore-local bookstore-local-tls --cert=./bookstore-local.pem --key=./bookstore-local-key.pem
最后,我们应该在 etc/helm/projectname/templates 文件夹中的 _helpers.tpl 文件中定义新应用程序。您可以从现有应用程序复制配置,并根据新应用程序进行修改。以下是 WebPublic 应用程序的 _helpers.tpl 文件示例。
{{- define "bookstore.hosts.webpublic" -}}
{{- print "https://" (.Values.global.hosts.webpublic | replace "[RELEASE_NAME]" .Release.Name) -}}
{{- end -}}
之后,我们需要为新应用程序创建一个新的 Helm chart。您可以从现有应用程序复制配置,并根据新应用程序进行修改。以下是 WebPublic 应用程序的 webpublic Helm chart 示例。
# values.yaml
image:
repository: "bookstore/webpublic"
tag: "latest"
pullPolicy: IfNotPresent
authServer:
clientSecret: "1q2w3e*"
# Chart.yaml
apiVersion: v2
name: webpublic
appVersion: "1.0"
description: Bookstore 公共 Web 应用程序
version: 1.0.0
type: application
# webpublic.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ .Release.Name }}-{{ .Chart.Name }}"
spec:
selector:
matchLabels:
app: "{{ .Release.Name }}-{{ .Chart.Name }}"
template:
metadata:
labels:
app: "{{ .Release.Name }}-{{ .Chart.Name }}"
spec:
containers:
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
imagePullPolicy: "{{ .Values.image.pullPolicy }}"
name: "{{ .Release.Name }}-{{ .Chart.Name }}"
ports:
- name: "http"
containerPort: 80
env:
- name: "DOTNET_ENVIRONMENT"
value: "{{ .Values.global.dotnetEnvironment }}"
- name: "App__SelfUrl"
value: "{{ include "bookstore.hosts.webpublic" . }}"
- name: App__EnablePII
value: "{{ .Values.global.enablePII }}"
- name: "AuthServer__Authority"
value: "{{ include "bookstore.hosts.authserver" . }}"
- name: "AuthServer__ClientSecret"
value: "{{ .Values.authServer.clientSecret }}"
- name: "AuthServer__IsOnK8s"
value: "true"
- name: "AuthServer__MetaAddress"
value: "http://{{ .Release.Name }}-authserver"
- name: "RemoteServices__Default__BaseUrl"
value: "http://{{ .Release.Name }}-webgateway"
...
# webpublic-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
name: "{{ .Release.Name }}-{{ .Chart.Name }}"
name: "{{ .Release.Name }}-{{ .Chart.Name }}"
spec:
ports:
- name: "80"
port: 80
selector:
app: "{{ .Release.Name }}-{{ .Chart.Name }}"
# webpublic-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: "{{ .Release.Name }}-{{ .Chart.Name }}"
annotations:
nginx.ingress.kubernetes.io/rewrite-target: "/"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
nginx.ingress.kubernetes.io/proxy-buffer-size: "32k"
nginx.ingress.kubernetes.io/proxy-buffers-number: "8"
cert-manager.io/cluster-issuer: "letsencrypt"
spec:
ingressClassName: "nginx"
tls:
- hosts:
- "{{ (include "bookstore.hosts.webpublic" .) | trimPrefix "https://" }}"
secretName: "{{ .Values.global.tlsSecret }}"
rules:
- host: "{{ (include "bookstore.hosts.webpublic" .) | trimPrefix "https://" }}"
http:
paths:
- path: /
pathType: "Prefix"
backend:
service:
name: "{{ .Release.Name }}-{{ .Chart.Name }}"
port:
number: 80
创建 Helm chart 后,您可以在 ABP Studio 中刷新子图表。
然后,更新元数据信息:右键单击应用程序 子图表,选择属性,这将打开图表属性窗口。您可以在元数据选项卡中进行编辑。
在图表属性 -> Kubernetes 服务选项卡中,添加服务名称正则表达式模式 Kubernetes 服务。
最后但同样重要的是,我们需要为 identity 微服务配置 helm chart 环境变量。
# identity.yaml
# 在 "env:" 部分添加这行
- name: "OpenIddict__Applications__WebPublic__RootUrl"
value: "{{ include "bookstore.hosts.webpublic" . }}"
自定义应用程序模板
您可以根据需要自定义应用程序模板。通过打开根目录中的 _templates 文件夹,然后打开 web 文件夹,向模板添加新的配置、依赖项或模块。根据需要修改 web 模板。命名约定规定,当创建应用程序时,microservicename 代表应用程序的名称。在模板文件中使用 microservicename 进行动态命名。在 web 文件夹中,有 3 个子文件夹:Blazor、BlazorServer 和 MVC。您可以根据创建新应用程序时选择的 UI 框架自定义模板。
抠丁客










