Mark的技术博客

SAP顾问 | 咨询专家 | IT与AI技术探索者

吴让宇(Mark)

吴让宇(Mark)

SAP顾问 | 咨询专家 | IT与AI技术探索者

吴让宇(Mark)的个人技术博客,专注于SAP系统实施、行业方案咨询、IT技术与AI技术的研究与分享。

SAP Fiori ABAP CDS OData Dify Docker AI LLM

最新文章

Dify 本地私有化部署(保姆级教程)

💡本文背景
Dify 是一个开源的 LLM 应用开发平台,支持私有化部署,数据完全掌握在自己手中。本文记录了通过 VMware + Linux + Docker Compose 方式从零部署 Dify 的完整过程。

原文参考:Dify本地私有化部署(保姆级教程) - 知乎

📖 Dify 简介

Dify 是一个开源的 LLM 应用开发平台,可以理解为”可私有化部署的扣子(Coze)”。

核心能力:

  • 可视化工作流编辑器:拖拽式编排
  • 多模型支持:OpenAI、DeepSeek、Llama、通义千问等
  • 三大核心功能:RAG、Agent、工作流
💬为什么选择 Dify?
  • 开源免费:代码在 GitHub 上,想改就改
  • 数据私有:部署在自己服务器上,数据不外传
  • 功能完整:对标扣子,该有的都有
  • 社区活跃:插件多、文档全、踩坑了有人帮

🔀 部署方式对比

部署方式 适用场景 优点 缺点
Docker Compose 正式部署 组件完整、功能全面 需要 Linux 环境
VMware 虚拟机 本地学习/测试 环境隔离、可快照恢复 资源占用较高
云服务器 公网访问 直接对外服务、访问方便 持续产生费用

本文选择 VMware + Linux + Docker Compose 方案,在 Windows 上开虚拟机部署,随便折腾,坏了快照一恢复即可。

配置要求

资源 最低配置 推荐配置
CPU 2 核 4 核
内存 8 GB 16 GB
磁盘 20 GB 50 GB
📌生产环境建议 4 核 16 GB 起步。

🖥️ VMware 环境搭建

在 VMware 中克隆一份 Rocky 9.4 系统用于部署 Dify:

VMware 克隆 Rocky 9.4 系统

网络模式选择

  • 桥接模式:虚拟机和主机同网段,局域网内可直接访问
  • NAT 模式:虚拟机通过主机上网,适合本地测试

配置静态 IP

⚠️必须配置静态 IP
避免每次重启后 IP 变化导致后续访问失败。

以 Rocky 9.4 带可视化界面为例,直接在网络设置中配置:

配置静态 IP

关闭防火墙

⚠️仅限测试环境
测试环境建议关闭防火墙,避免后续连接问题。
1
2
systemctl stop firewalld.service
systemctl disable firewalld.service

安装 Docker 环境

配置镜像加速(必须配置,否则下载极慢):

1
vim /etc/docker/daemon.json

写入以下内容:

1
2
3
4
5
6
7
8
9
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.mirrors.tuna.tsinghua.edu.cn",
"https://mirror.ccs.tencentyun.com",
"https://hub-mirror.c.163.com"
],
"max-concurrent-downloads": 10
}

Docker 镜像加速配置

重启使配置生效:

1
2
systemctl daemon-reload
systemctl restart docker.service

安装完成后,验证 Docker 版本:

Docker 安装完成

🚀 部署 Dify

下载源码

方式一:Gitee 镜像(推荐国内用户)

1
git clone https://gitee.com/dify_ai/dify.git
💡Gitee vs GitHub
  • Gitee 下载速度快,适合国内网络,代码与 GitHub 同步
  • GitHub 官方仓库可能因网络问题无法直接克隆,可配置代理解决

方式二:GitHub 官方仓库

1
git clone https://github.com/langgenius/dify.git

如果 GitHub 直接克隆失败(国内常见问题),会报如下错误:

GitHub 克隆失败

此时切换到 Gitee 镜像即可解决。

准备配置文件

1
2
3
4
5
# 进入 docker 目录
cd dify/docker

# 复制环境变量模板
cp .env.example .env

复制 .env 环境变量模板

配置环境变量(关键!)

编辑 .env 文件,重点配置以下项:

1
2
3
4
5
6
7
8
9
10
# 设置访问地址(替换为虚拟机实际 IP)
APP_API_URL=http://你的虚拟机IP
CONSOLE_API_URL=http://你的虚拟机IP

# 生成强密钥
SECRET_KEY=your_generated_secret_key

# 数据库密码
POSTGRES_PASSWORD=你的强密码
REDIS_PASSWORD=你的强密码
⚠️生成密钥命令
使用 openssl rand -base64 42 生成安全密钥。

如果 API 地址配置不正确,前端将无法调通 API,访问时会报 404。

一键启动

/root/dify/docker 目录下执行:

1
docker-compose up -d

首次启动会自动拉取镜像,约 5-10 分钟(取决于网速):

docker-compose 拉取镜像中

镜像拉取完成,所有容器启动成功:

docker-compose 启动完成

💡验证部署
所有容器状态为 Up 即表示部署成功。

⚙️ 初始化 Dify

创建管理员账号

浏览器访问 http://你的虚拟机IP,进入安装引导页:

Dify 安装引导页

填写邮箱和密码创建管理员账号:

创建管理员账号

配置大模型

进入 设置 → 模型供应商,可以看到支持的各种模型:

模型供应商列表

💥推荐
没有 API Key 的用户,推荐使用 DeepSeek通义千问,注册会送免费额度。

以 DeepSeek 为例,配置 API Key:

配置 DeepSeek API Key

配置完成后,模型状态变为可用:

模型配置完成

📋 部署流程总结



graph LR
    A[VMware 环境搭建] --> B[安装 Docker]
    B --> C[配置镜像加速]
    C --> D[下载 Dify 源码]
    D --> E[配置环境变量]
    E --> F[docker-compose up]
    F --> G[初始化管理员]
    G --> H[配置大模型 API]
    H --> I[🎉 部署完成]

ℹ️下一步
部署完成后,可以在 Dify 上搭建智能体、配置工作流和 RAG 知识库。

Nginx 反向代理与负载均衡

ℹ️深入理解 Nginx 反向代理和负载均衡配置与实战应用

🎯 学习目标

  • 理解反向代理的原理和应用场景
  • 掌握 Nginx 负载均衡的多种策略
  • 学习高可用架构的配置方法
  • 实战:搭建生产级负载均衡系统

📋 反向代理详解

🔍 什么是反向代理?

反向代理(Reverse Proxy):代理服务器接收客户端请求,然后将请求转发给后端服务器,后端服务器处理完后将结果返回给代理服务器,代理服务器再返回给客户端。



graph LR
    A[客户端] --> B[Nginx反向代理]
    B --> C[后端服务器1]
    B --> D[后端服务器2]
    B --> E[后端服务器3]

    C --> B
    D --> B
    E --> B
    B --> A

🏗️ 反向代理的优势

优势 说明
负载均衡 分发请求到多台服务器,提高整体性能
安全性 隐藏后端服务器真实IP,增强安全性
缓存 缓存静态资源,减轻后端压力
SSL 终止 统一处理 HTTPS,简化后端配置
统一入口 多个服务通过同一个域名访问

🚀 反向代理基础配置

简单反向代理

1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 80;
server_name api.example.com;

location / {
proxy_pass http://localhost:3000; # 后端服务地址
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

常用代理头说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 传递原始主机头
proxy_set_header Host $host;

# 传递客户端真实IP
proxy_set_header X-Real-IP $remote_addr;

# 传递客户端IP链(包含所有代理IP)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# 传递原始协议(http/https)
proxy_set_header X-Forwarded-Proto $scheme;

# 传递原始请求URI
proxy_set_header X-Forwarded-Host $host:$server_port;

⚖️ 负载均衡详解

🔄 负载均衡策略

Nginx 支持多种负载均衡策略,每种策略适用于不同的场景:



graph TD
    A[Nginx负载均衡] --> B[轮询策略]
    A --> C[最少连接]
    A --> D[IP哈希]
    A --> E[权重分配]
    A --> F[热备模式]

    B --> B1[默认策略<br/>平均分配请求]
    C --> C1[连接数最少<br/>优先分配]
    D --> D1[基于IP计算<br/>会话保持]
    E --> E1[按性能权重<br/>分配请求]
    F --> F1[备用服务器<br/>故障时启用]

1. 轮询策略(默认)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}

server {
listen 80;
server_name www.example.com;

location / {
proxy_pass http://backend;
}
}

特点:按顺序逐一分配请求,平均分配负载。

2. 权重分配

1
2
3
4
5
upstream backend {
server 192.168.1.10:8080 weight=3; # 高性能服务器,权重为3
server 192.168.1.11:8080 weight=2; # 中等性能服务器
server 192.168.1.12:8080 weight=1; # 低性能服务器
}

特点:根据服务器性能设置权重,性能越强权重越高。

3. 最少连接

1
2
3
4
5
6
upstream backend {
least_conn; # 启用最少连接策略
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}

特点:优先将请求分配给当前连接数最少的服务器。

4. IP 哈希

1
2
3
4
5
6
upstream backend {
ip_hash; # 启用IP哈希策略
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}

特点:根据客户端IP计算哈希值,同一IP总是访问同一服务器,解决会话保持问题。

5. 热备模式

1
2
3
4
upstream backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080 backup; # 标记为备用服务器
}

特点:备用服务器只在主服务器故障时才接管请求。


🛠️ 高级负载均衡配置

健康检查

1
2
3
4
5
upstream backend {
server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 max_fails=3 fail_timeout=30s;
}

参数说明

  • max_fails=3:30秒内失败3次则标记为不可用
  • fail_timeout=30s:失败后30秒内不再分配请求

完整配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# 定义后端服务器组
upstream backend_servers {
# 负载均衡策略
least_conn;

# 服务器配置
server 192.168.1.10:8080 weight=3 max_fails=3 fail_timeout=30s;
server 192.168.1.11:8080 weight=2 max_fails=3 fail_timeout=30s;
server 192.168.1.12:8080 weight=1 max_fails=3 fail_timeout=30s;

# 保持连接
keepalive 32;
}

server {
listen 80;
server_name www.example.com;

# 日志配置
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

location / {
# 代理配置
proxy_pass http://backend_servers;

# 请求头设置
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# 缓冲设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;
}

# 健康检查端点
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}

🔒 反向代理安全配置

隐藏后端服务器信息

1
2
3
4
5
6
# 隐藏后端服务器响应头
proxy_hide_header X-Powered-By;
proxy_hide_header Server;

# 设置自定义响应头
proxy_set_header Server "My-Server";

访问控制

1
2
3
4
5
6
7
8
9
10
11
12
13
# 限制IP访问
location /admin {
proxy_pass http://backend;
allow 192.168.1.0/24; # 允许内网访问
deny all; # 拒绝其他所有访问
}

# 基本认证
location /api {
proxy_pass http://backend;
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
}

📊 负载均衡监控

状态监控配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 编译时需要添加 nginx-module-sts 模块
# 或使用 nginx-module-vts 模块

server {
listen 80;
server_name status.example.com;

location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
}

监控指标说明

1
2
3
4
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
Reading: 6 Writing: 179 Waiting: 106

指标含义

  • Active connections:当前活跃连接数
  • accepts:已接受的总连接数
  • handled:已处理的总连接数
  • requests:已处理的总请求数
  • Reading:正在读取请求头的连接数
  • Writing:正在读取请求体或处理请求的连接数
  • Waiting:空闲连接数

🎯 实战案例

案例1:微服务架构负载均衡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 用户服务
upstream user_service {
least_conn;
server user1.example.com:8001 weight=2;
server user2.example.com:8001 weight=1;
}

# 订单服务
upstream order_service {
ip_hash;
server order1.example.com:8002;
server order2.example.com:8002;
}

# 支付服务
upstream payment_service {
server payment1.example.com:8003 backup;
server payment2.example.com:8003;
}

server {
listen 80;
server_name api.example.com;

# 用户服务路由
location /api/users {
proxy_pass http://user_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# 订单服务路由
location /api/orders {
proxy_pass http://order_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# 支付服务路由
location /api/payment {
proxy_pass http://payment_service;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

案例2:静态+动态分离

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 静态资源服务器
upstream static_servers {
server static1.example.com;
server static2.example.com;
}

# 动态应用服务器
upstream app_servers {
least_conn;
server app1.example.com:8080;
server app2.example.com:8080;
}

server {
listen 80;
server_name www.example.com;

# 静态资源代理
location ~* \.(jpg|jpeg|png|gif|css|js|ico|svg|woff|woff2)$ {
proxy_pass http://static_servers;
expires 30d;
add_header Cache-Control "public, immutable";
}

# 动态请求代理
location / {
proxy_pass http://app_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}

🛡️ 高可用架构

Keepalived + Nginx 高可用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 安装 keepalived
sudo apt install keepalived

# 配置文件 /etc/keepalived/keepalived.conf
vrrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
interval 2
weight -20
}

vrrp_instance VI_1 {
state MASTER # 主服务器
interface eth0 # 网卡名称
virtual_router_id 51 # 虚拟路由ID
priority 100 # 优先级
advert_int 1

authentication {
auth_type PASS
auth_pass 1234
}

virtual_ipaddress {
192.168.1.100 # 虚拟IP
}

track_script {
check_nginx
}
}

📝 故障排查

常见问题及解决方案

问题 原因 解决方案
502 Bad Gateway 后端服务不可用 检查后端服务状态和配置
504 Gateway Timeout 后端响应超时 增加 proxy_read_timeout
无法连接后端 防火墙阻止 检查防火墙规则
会话丢失 负载均衡策略 使用 ip_hash 或会话共享

🔗 相关资源

学习资源


💡 实践建议

[success] 学习建议

  1. 从简单的反向代理开始练习
  2. 逐步尝试不同的负载均衡策略
  3. 在测试环境中模拟故障场景
  4. 学习监控和日志分析方法
  5. 了解高可用架构的配置

下一步:继续学习 03_Nginx性能优化与安全配置_最佳实践

Nginx 实战配置示例

ℹ️生产环境常用 Nginx 配置模板和实战案例

🎯 学习目标

  • 掌握常见业务场景的 Nginx 配置
  • 学习生产环境的最佳实践
  • 了解微服务架构的 Nginx 部署
  • 实战:完整的项目部署配置

📋 目录结构

推荐的配置文件组织

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/etc/nginx/
├── nginx.conf # 主配置文件
├── conf.d/
│ ├── upstream.conf # 后端服务器组配置
│ ├── ssl.conf # SSL配置
│ └── security.conf # 安全配置
├── sites-available/ # 可用站点
│ ├── website1.conf
│ ├── website2.conf
│ └── api.conf
├── sites-enabled/ # 已启用站点(软链接)
└── snippets/ # 配置片段
├── ssl-params.conf
├── proxy-params.conf
└── wp-common.conf

🚀 实战场景配置

场景1:静态网站部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# /etc/nginx/sites-available/static-website.conf
server {
listen 80;
listen [::]:80;

server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.htm;

# 字符集
charset UTF-8;

# 日志配置
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;

# 主要路由
location / {
try_files $uri $uri/ =404;
}

# 静态资源缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ {
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}

# 禁止访问隐藏文件
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}

# 安全响应头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}

场景2:HTTPS 强制跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# HTTP 重定向到 HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;

# Let's Encrypt 验证路径
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}

# 其他请求重定向到 HTTPS
location / {
return 301 https://$server_name$request_uri;
}
}

# HTTPS 配置
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;

# SSL 证书配置
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/nginx/snippets/ssl-params.conf;

# 其他配置...
root /var/www/example.com;
index index.html;

location / {
try_files $uri $uri/ =404;
}
}

场景3:反向代理 Node.js 应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
upstream nodejs_backend {
server 127.0.0.1:3000;
keepalive 64;
}

server {
listen 80;
server_name api.example.com;

# 日志配置
access_log /var/log/nginx/api.access.log;
error_log /var/log/nginx/api.error.log;

location / {
proxy_pass http://nodejs_backend;
include /etc/nginx/snippets/proxy-params.conf;

# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}

# 静态文件直接由 Nginx 处理
location /static {
alias /var/www/nodejs-app/public;
expires 30d;
add_header Cache-Control "public";
}

# 健康检查
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}

场景4:微服务架构网关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# 定义多个后端服务
upstream user_service {
least_conn;
server user1.example.com:8001 weight=2;
server user2.example.com:8001 weight=1;
keepalive 32;
}

upstream order_service {
ip_hash;
server order1.example.com:8002;
server order2.example.com:8002;
keepalive 32;
}

upstream payment_service {
server payment1.example.com:8003 backup;
server payment2.example.com:8003;
keepalive 32;
}

upstream frontend_service {
server frontend1.example.com:3000;
server frontend2.example.com:3000;
}

server {
listen 80;
server_name api.example.com;

# 用户服务
location /api/users {
proxy_pass http://user_service;
include /etc/nginx/snippets/proxy-params.conf;
}

# 订单服务
location /api/orders {
proxy_pass http://order_service;
include /etc/nginx/snippets/proxy-params.conf;
}

# 支付服务
location /api/payment {
proxy_pass http://payment_service;
include /etc/nginx/snippets/proxy-params.conf;
}

# 前端应用
location / {
proxy_pass http://frontend_service;
include /etc/nginx/snippets/proxy-params.conf;
}
}

🛠️ 配置片段模板

SSL 参数配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# /etc/nginx/snippets/ssl-params.conf

# SSL 协议配置
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;

# SSL 会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;

# 安全响应头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

代理参数配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# /etc/nginx/snippets/proxy-params.conf

# 基础代理头
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $http_host;

# 超时设置
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;

# 缓冲设置
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
proxy_busy_buffers_size 8k;

# HTTP 版本
proxy_http_version 1.1;
proxy_set_header Connection "";

📱 实战项目案例

案例1:Vue.js 单页应用部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
server {
listen 80;
server_name spa.example.com;

root /var/www/vue-spa;
index index.html;

# 历史模式路由配置
location / {
try_files $uri $uri/ /index.html;
}

# API 请求代理
location /api {
proxy_pass http://backend-api:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# 静态资源缓存
location /js {
expires 1y;
add_header Cache-Control "public, immutable";
}

location /css {
expires 1y;
add_header Cache-Control "public, immutable";
}

location /images {
expires 1y;
add_header Cache-Control "public, immutable";
}
}

案例2:WordPress 网站部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# HTTP 重定向
server {
listen 80;
server_name blog.example.com;
return 301 https://$server_name$request_uri;
}

# HTTPS 配置
server {
listen 443 ssl http2;
server_name blog.example.com;

root /var/www/html;
index index.php index.html index.htm;

# SSL 配置
ssl_certificate /etc/letsencrypt/live/blog.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blog.example.com/privkey.pem;
include /etc/nginx/snippets/ssl-params.conf;

# 日志
access_log /var/log/nginx/blog.access.log;
error_log /var/log/nginx/blog.error.log;

# WordPress 标准配置
location / {
try_files $uri $uri/ /index.php?$args;
}

# PHP 处理
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
}

# WordPress 管理后台限制
location ~* wp-admin {
allow 192.168.1.0/24;
deny all;
}

# 禁止访问敏感文件
location ~* /(?:\.htaccess|\.htpasswd|\.git|\.svn|wp-config\.php) {
deny all;
}

# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 365d;
add_header Cache-Control "public, immutable";
}
}

案例3:Docker 容器服务代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# Docker 服务网格配置
upstream docker_services {
server docker1:8080;
server docker2:8080;
server docker3:8080;
}

server {
listen 80;
server_name docker.example.com;

# 健康检查
location /health {
proxy_pass http://docker_services/health;
access_log off;
}

# 主要服务
location / {
proxy_pass http://docker_services;
include /etc/nginx/snippets/proxy-params.conf;

# Docker 特殊配置
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

# WebSocket 支持
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

# 容器监控
location /metrics {
proxy_pass http://docker_services/metrics;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
}

🔧 监控和运维

状态监控配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Nginx 状态页面
server {
listen 80;
server_name status.example.com;

location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}

# 服务器信息
location /server_info {
default_type text/plain;
return 200 "Server: $hostname\nTime: $time_local\n";
}
}

日志分析脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/bash
# nginx_log_analyzer.sh

# 分析访问最多的 IP
echo "Top 10 IPs:"
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

# 分析访问最多的 URL
echo -e "\nTop 10 URLs:"
awk '{print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -10

# 分析 HTTP 状态码
echo -e "\nHTTP Status Codes:"
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr

🚨 故障排查

常见问题解决

1. 502 Bad Gateway

1
2
3
4
5
6
7
8
9
10
# 增加超时时间
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;

# 检查后端服务状态
upstream backend {
server backend1:8080 max_fails=3 fail_timeout=30s;
server backend2:8080 max_fails=3 fail_timeout=30s;
}

2. 413 Request Entity Too Large

1
2
3
# 增加上传文件大小限制
client_max_body_size 50M;
client_body_buffer_size 128k;

3. 504 Gateway Timeout

1
2
3
4
5
# 增加代理超时时间
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;

📝 配置管理最佳实践

1. 版本控制

1
2
3
4
5
6
7
8
# 使用 git 管理配置文件
cd /etc/nginx
sudo git init
sudo git add .
sudo git commit -m "Initial nginx configuration"

# 配置变更前备份
sudo cp nginx.conf nginx.conf.backup

2. 配置测试

1
2
3
4
5
# 测试配置文件语法
sudo nginx -t

# 测试特定站点配置
sudo nginx -t -c /etc/nginx/sites-available/mysite.conf

3. 平滑重载

1
2
3
4
5
# 重新加载配置(不中断服务)
sudo nginx -s reload

# 或者使用 systemctl
sudo systemctl reload nginx

🔗 相关资源

学习资源


💡 实践建议

[success] 部署建议

  1. 开发环境先充分测试
  2. 使用版本控制管理配置
  3. 建立配置备份机制
  4. 设置监控和告警
  5. 定期更新和安全检查
  6. 准备应急处理预案

📚 学习路径总结

恭喜你完成了 Nginx 学习笔记的全套内容!现在你已经掌握:

  1. 基础入门01_Nginx入门指南_基础概念
  2. 反向代理与负载均衡02_Nginx反向代理与负载均衡_实战教程
  3. 性能优化与安全配置03_Nginx性能优化与安全配置_最佳实践
  4. 实战配置04_Nginx实战配置示例_项目部署

下一步建议:

  • 在测试环境搭建完整的 Nginx 服务
  • 尝试部署实际项目
  • 学习更多高级功能和调优技巧
  • 关注 Nginx 社区最新动态

祝你学习愉快!🎉

Nginx 性能优化与安全配置

ℹ️生产环境 Nginx 性能调优和安全加固最佳实践

🎯 学习目标

  • 掌握 Nginx 性能优化的核心参数
  • 学习生产环境的安全配置策略
  • 了解高并发场景的优化技巧
  • 实战:配置生产级 Nginx 服务器

⚡ 性能优化配置

1️⃣ 工作进程优化

1
2
3
4
5
6
7
8
9
10
11
12
# 根据CPU核心数自动设置工作进程数
worker_processes auto;

# 将每个工作进程绑定到特定的CPU核心
worker_cpu_affinity auto;

# 每个工作进程的最大连接数
events {
worker_connections 4096; # 默认1024,可提升到4096或更高
use epoll; # Linux系统使用epoll事件模型
multi_accept on; # 允许一次接受多个连接
}

2️⃣ 文件描述符限制

1
2
3
4
5
6
# /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535

# /etc/sysctl.conf
fs.file-max = 2097152

3️⃣ 核心性能参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
http {
# 基础性能优化
sendfile on; # 使用sendfile系统调用
tcp_nopush on; # 数据包累积到一定大小再发送
tcp_nodelay on; # 禁用Nagle算法,减少延迟
keepalive_timeout 30; # 保持连接时间(秒)

# 缓冲区优化
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
output_buffers 1 32k;
postpone_output 1460;

# 连接优化
keepalive_requests 100; # 每个连接最大请求数
reset_timedout_connection on; # 重置超时连接

# 文件缓存
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}

4️⃣ Gzip 压缩配置

1
2
3
4
5
6
7
8
9
10
11
12
# 启用Gzip压缩
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss
application/rss+xml font/truetype font/opentype
application/vnd.ms-fontobject image/svg+xml;

# 排除不需要压缩的文件类型
gzip_disable "msie6";

🔒 安全配置

1️⃣ 隐藏版本信息

1
2
3
4
5
# 在http块中配置
http {
server_tokens off; # 隐藏Nginx版本号
more_set_headers 'Server: MyWebServer'; # 自定义服务器名称
}

2️⃣ 限制请求大小

1
2
3
4
5
6
7
8
9
10
11
12
# 限制请求体大小,防止DDoS攻击
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;

# 限制请求速率
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_req zone=one burst=20 nodelay;

# 限制连接数
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 10;

3️⃣ SSL/TLS 安全配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
server {
listen 443 ssl http2;
server_name example.com;

# SSL证书配置
ssl_certificate /etc/nginx/ssl/example.com.crt;
ssl_certificate_key /etc/nginx/ssl/example.com.key;

# SSL协议和加密套件
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers on;

# SSL会话缓存
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx/ssl/ca-bundle.crt;

# 安全响应头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
}

4️⃣ 访问控制和IP限制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 限制特定路径的访问
location /admin {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
}

# 阻止特定User-Agent
if ($http_user_agent ~* (wget|curl|scanner) ) {
return 403;
}

# 阻止特定Referer
valid_referers none blocked example.com *.example.com;
if ($invalid_referer) {
return 403;
}

5️⃣ 防止常见攻击

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 防止SQL注入
if ($args ~* "union.*select.*\(" ) {
return 403;
}

# 防止文件包含攻击
if ($args ~* "php://input" ) {
return 403;
}

# 防止XSS攻击
if ($args ~* "<script>" ) {
return 403;
}

# 限制访问敏感文件
location ~ /\.(htaccess|htpasswd|git|svn) {
deny all;
}

📊 缓存配置优化

静态资源缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 静态文件缓存
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg)$ {
expires 365d;
add_header Cache-Control "public, immutable";
access_log off;
}

# HTML文件缓存
location ~* \.html$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
}

# API响应不缓存
location /api {
expires -1;
add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
}

Proxy Cache 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 定义缓存路径和参数
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off;

server {
location / {
# 启用代理缓存
proxy_cache my_cache;

# 缓存键配置
proxy_cache_key "$scheme$request_method$host$request_uri";

# 缓存有效期
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;

# 缓存控制头
add_header X-Cache-Status $upstream_cache_status;

# 代理设置
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}

# 绕过缓存
location /api {
proxy_cache_bypass $http_cache_control;
proxy_no_cache $http_cache_control;
proxy_pass http://backend;
}
}

🔧 日志配置优化

访问日志优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 自定义日志格式
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';

log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time '
'$upstream_addr $upstream_status';

# 访问日志配置
access_log /var/log/nginx/access.log main buffer=32k flush=5s;

# 静态资源不记录日志
location ~* \.(jpg|jpeg|png|gif|css|js|ico|woff|woff2)$ {
access_log off;
log_not_found off;
}

错误日志优化

1
2
3
4
5
6
7
# 错误日志级别:debug, info, notice, warn, error, crit, alert, emerg
error_log /var/log/nginx/error.log warn;

# 特定目录的错误日志
location /api {
error_log /var/log/nginx/api_error.log info;
}

🚀 系统级优化

Linux内核参数优化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# /etc/sysctl.conf

# 网络连接优化
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 30

# TCP缓冲区优化
net.ipv4.tcp_rmem = 4096 87380 67108864
net.ipv4.tcp_wmem = 4096 65536 67108864
net.core.rmem_max = 67108864
net.core.wmem_max = 67108864

# 文件描述符限制
fs.file-max = 2097152

# 应用优化
net.ipv4.ip_local_port_range = 1024 65535
net.core.netdev_max_backlog = 16384

应用配置后生效

1
2
3
4
5
# 立即生效
sudo sysctl -p

# 查看当前配置
sudo sysctl -a

📈 性能监控

状态监控配置

1
2
3
4
5
6
7
8
9
10
11
12
13
# 编译时添加 stub_status 模块
server {
listen 80;
server_name status.example.com;

location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow 192.168.1.0/24;
deny all;
}
}

性能分析工具

1
2
3
4
5
6
7
8
# 使用ab工具进行压力测试
ab -n 10000 -c 100 http://example.com/

# 使用wrk工具
wrk -t12 -c400 -d30s http://example.com/

# 使用nginx-amplify监控
# https://nginx.com/amplify/

🛡️ 安全加固清单

✅ 基础安全配置

  • 隐藏 Nginx 版本信息
  • 限制请求大小和速率
  • 配置 SSL/TLS 安全协议
  • 设置安全响应头
  • 限制敏感文件访问
  • 配置访问控制和IP限制

✅ 高级安全配置

  • 配置防火墙规则
  • 启用 Fail2Ban 防护
  • 配置 HTTPS 强制跳转
  • 实施速率限制
  • 配置日志监控
  • 定期更新 Nginx 版本

📝 生产环境配置示例

完整的生产级配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 4096;
use epoll;
multi_accept on;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$request_time $upstream_response_time';

access_log /var/log/nginx/access.log main buffer=32k flush=5s;

# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 30;
keepalive_requests 100;
reset_timedout_connection on;

# 压缩配置
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/json application/javascript application/xml+rss;

# 安全配置
server_tokens off;
client_max_body_size 10m;
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=addr:10m;

# 缓存配置
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m
max_size=1g inactive=60m use_temp_path=off;

# 包含站点配置
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}

🔧 故障排查

常见性能问题

问题 原因 解决方案
连接数不足 worker_connections 太低 增加到 4096 或更高
CPU使用率高 worker_processes 不合理 设置为 auto 或 CPU核心数
响应慢 没有启用缓存 配置 proxy_cache
内存占用高 缓冲区设置过大 调整 buffer 参数

调优建议

  1. 逐步调优:一次只调整一个参数,观察效果
  2. 监控指标:使用监控工具跟踪性能变化
  3. 压力测试:在测试环境验证配置效果
  4. 日志分析:定期分析访问和错误日志
  5. 定期维护:清理旧日志,检查配置文件

🔗 相关资源

学习资源


💡 实践建议

[success] 优化建议

  1. 先在测试环境验证所有配置
  2. 逐步优化,一次调整一个参数
  3. 使用监控工具跟踪性能指标
    1. 定期备份配置文件
    2. 建立配置版本管理

下一步:继续学习 04_Nginx实战配置示例_项目部署

SAP UI 风格的演进

经典 SAP GUI

SAP GUI 是 SAP 传统的操作界面,虽然”丑陋”但 ==简洁、高效、风格统一==,成为 SAP 的经典符号。

SAP GUI

新一代 Fiori

随着企业用户对全场景(anytime, anywhere)业务需求的增长,Fiori 逐步成为 SAP 新一代 UI 风格。

Fiori UI

💡Fiori 的优势
  • 清爽的设计风格,user-friendly 的操作方式
  • 跨终端通用(Mobile / Tablet / Desktop)
  • 经过性能调优后,反应速度同样很快

Fiori 技术架构

Fiori 应用程序由三层架构组成:

Fiori 架构

层级 组件 说明
底层 ==SAP HANA== 列存储内存数据库,按开发 guidance 做速度极快
中层 ==SAP NetWeaver== 后台平台,业务逻辑由 ABAP 完成,基于 CDS 建模
前端 ==SAPUI5== 基于 HTML5 / CSS / JS 的前台开发技术
ℹ️SAP Gateway
SAP Gateway 是 NetWeaver 上的组件,负责将 CDS 业务模型发布为 OData service,供前端 SAPUI5 程序使用。

SAPUI5 的 MVC 架构

SAPUI5 架构

SAPUI5 前端采用经典 MVC(Model-View-Controller)设计模型,掌握 MVC 原理是理解 Fiori 运行机制的基础。

技能储备

必要技能

技能 说明
ABAP SAP 开发人员必备技能
CDS (Core Data Service) 建模基础,必须掌握
CDS annotations 通过 annotation 控制 Fiori 页面行为
SAP Gateway 管理 OData service
OData 了解 OData 结构和 annotation,是 Fiori 开发基础

开发环境

工具 说明
SAP ADT 基于 Eclipse 的 ABAP Development Tool,传统 SE80 无法开发 CDS
SAP Web IDE 开发 Fiori 前台

辅助技能

  • SAPUI5 — Fiori 的控件库
  • JavaScript — 做前台逻辑调整

了解更好

  • HTML
  • CSS
💬要点
SAP 提供了完整的 Fiori 框架,通过 CDS annotation 即可完成页面描述,==不写任何 HTML / CSS / JavaScript 代码也能完成 Fiori 开发==。

关键参考资源

设计规范的作用

在很多产品经理和 Axure 的文章中都不太被重视或提及,实际上它非常重要。制定设计规范 ≠ 高保真,也不代表低效率和重视界面设计,它有以下几个重要作用:

作用 说明
提升效率 减少产品设计过程中对元件位置摆放和尺寸大小的记忆与思考,有了设计规范,这些操作都事半功倍
提高可读性 极大提高整个原型文档的可阅读性,向开发团队传递统一的产品设计理念,便于理解
突出重点 将界面元素重点和逻辑重点凸显出来,不仅不会干扰 UI 设计,还能帮助 UI 设计师正确理解你重视的要素
团队协同 帮助产品团队高效协同,多人参与时保持高度的表达一致性,便于开发团队和 UI 设计理解
💡经验之谈
在缺乏经验的时候,就把设计规范带入产品原型设计,这是一个很好的开始。这个过程你一定会走一些弯路,因为你无法准确预见到一定会用到哪些元件,但不要气馁。

网格和格栅

在开始做产品设计之前,需要先定义产品适用的设备,了解产品的基本尺寸比例,然后据此设置好格栅和网格。这样就能将界面中的各要素按照既定规则摆放,呈现整洁、美观的效果,减少临时调整,也为做出高质量的高保真原型打下坚实基础。

例一:手机端(iPhone 12 Pro)

参数 设置
尺寸比例 390px × 844px
网格 15px = 390 / 26,用作元件尺寸和间距的最小单位
无间距格栅 30px × 12;边距各 15px

格栅效果:

根据格栅设计的示例(尺寸、间距都与网格和格栅定义一致):

例二:Web 端(1920 × 1080)

参数 设置
尺寸比例 1920px × 1080px
网格 24px = 1920 / 80,用作元件尺寸和间距最小单位
有间距格栅 (格栅 48px + 间距 24px)× 26;边距各 24px

格栅效果:

根据格栅设计的示例:

⚠️注意
  • Axure 中只能使用 px 作为度量单位
  • 红线为全局辅助线,背景的方格即为网格
  • 格栅有很多种设计方法,主要是 UI 设计时应用,做原型一般只用概略格栅即可,目的是规范产品设计
  • 本图仅为一个网格设置的示例,请根据实际需要去设计格栅和网格

颜色

我们经常见到一些草图上只有灰黑白三个色,实际在表达原型时,需要更多的颜色以突出或表达不同元件的可用性、操作性、重要性。

💡建议
以上只是一个例子,可以查阅设计资料,建立自己喜欢或适用于项目的颜色规范。常用的元件可以设置到自己的元件库中,无需重复设计样式。

元件尺寸与文字

元件尺寸

元件尺寸与网格和格栅有直接关系,元件的尺寸最好是网格的倍数关系,但不一定是整数倍。

文字规范

  • 大部分基础元件可以直接在元件中输入文字——选中元件双击或敲回车即可
  • 元件的文字最小字号只能用 12,即使选择更小的字号,预览时也会被还原到 12
  • 因此元件尺寸不能太小,否则文字显示会受到很大的限制

📌小结
我们不需要过多地去考虑这个问题,因为原型不是设计图,表达正确的意图即可。了解以上三个基本点后,就可以开始准备原型的设计规范了。为了让设计规范有序制定并有效利用,还需要了解元件库的创建母版的创建,以及它们的应用。

简介

Obsidian 是一款跨平台个人知识管理与笔记工具,核心理念:

  • 本地优先 — 数据存储在本地,用户完全掌控
  • 数据主权 — 不依赖云端,隐私安全极高
  • 非线性知识组织 — 通过双向链接构建知识网络
ℹ️定价模式
采用”个人免费、商业付费”模式。个人用户无功能限制,商业场景需购买许可。增值服务仅两项:
  • Obsidian Sync(≈ $8/月)— 官方同步
  • 在线发布服务 — 发布笔记为网页
    两者均为可选,不影响核心功能。

核心亮点:双向链接与图谱视图

  • 双向链接:用 [[]] 语法为笔记建立关联,可追溯引用与被引用关系
  • 图谱视图:将笔记关联可视化,以节点形式展现知识网络,发现潜在联系

与同类工具对比

对比维度 Obsidian Notion 印象笔记 OneNote
数据存储 本地(自选备份) 云端 云端 云端+本地
收费模式 核心功能永久免费 基础免费,高级付费 免费版功能有限 免费
隐私安全 极高(不上传网络)
核心功能 双向链接、知识图谱、插件生态 数据库、看板、团队协作 网页剪藏、OCR 手写笔记、自由排版
适合人群 学生、研究者、写作者、程序员 团队协作者 信息搜集者 学生、手写需求者
学习成本 中等 极低
💡核心优势
Obsidian 将笔记所有权完全交还给用户,通过双向链接建立**真正的”知识体系”**而非”资料堆积”。

下载安装

📌下载地址
官方中文版安装包:Obsidian 安装包

安装步骤

步骤 1 — 双击 Obsidian-1.11.5.exe 启动安装,点击”运行”:

01-run

步骤 2 — 点击”下一步”:

02-next

步骤 3 — 选择安装路径(建议安装到非系统盘),点击”安装”:

步骤 4 — 等待进度条加载至 100%:

步骤 5 — 点击”完成”:

步骤 6 — 出现以下界面,安装成功:


初始配置与使用

创建知识库

步骤 1 — 语言选择”简体中文”,点击”创建”:

步骤 2 — 输入仓库名称,选择存储位置(建议非系统盘),点击”创建”:

步骤 3 — 创建成功:

启用工作区插件

步骤 1 — 点击左下角”设置” ⚙️

步骤 2 — 进入”核心插件” → 下滑找到并开启”工作区”

💡工作区插件
可保存页面布局设置,方便下次打开时恢复之前的工作状态。

使用注意事项

⚠️核心注意事项
  • 新手勿盲目追求插件 — 先掌握双向链接、知识图谱、基础编辑,再按需安装插件,避免界面复杂和运行卡顿
  • 定期备份知识库 — 本地存储虽安全,仍需定期备份(U盘、云盘),防止电脑故障导致数据丢失
  • 规范笔记命名 — 建议统一命名规则(如 2026-01-27-每日复盘),方便搜索管理,避免重名导致链接混乱
  • 合理使用标签与文件夹 — 标签用于跨文件夹分类,文件夹用于基础分类,两者结合使用

常见问题 FAQ

❓ 安装插件提示”安全模式已开启”

进入 设置 → 社区插件 → 关闭”安全模式”。

ℹ️无法访问社区插件市场?
需要特殊网络环境。无法访问时可搜索”Obsidian 插件离线安装包“,手动导入插件文件夹。

❓ 多设备同步笔记冲突或丢失

  • 使用官方 Obsidian Sync 服务(支持冲突自动合并)
  • 第三方云盘同步时,避免多端同时编辑,同步前关闭其他设备的 Obsidian
  • 笔记丢失可通过云盘版本历史回溯或从备份恢复

❓ Markdown 语法不熟悉,编辑效率低

  • 先掌握基础语法:加粗 **粗体**、斜体 *斜体*、标题 #、列表 - / 1.
  • 安装 “Auto Pair Markdown” 插件,自动补全语法符号
  • 创建 Markdown 语法模板,随时查阅

❓ 知识图谱过于混乱

  • 通过图谱视图筛选功能,按标签/文件夹过滤
  • 调整节点大小和距离,突出核心笔记
  • 定期整理:删除无效链接,合并相似笔记

❓ 如何迁移旧笔记到 Obsidian

  • 将旧笔记导出为 Markdown 格式(Evernote、Word 均支持导出 .md
  • 复制到 Obsidian 知识库文件夹,自动识别
  • 格式错乱可手动调整或使用 “Markdown Format Cleaner” 插件

❓ Obsidian 运行卡顿

  • 关闭无用插件,仅保留核心插件
  • 将知识库迁移至 SSD 硬盘
  • 定期清理缓存:设置 → 外观 → 清理缓存
  • 笔记超过 1000 篇时,考虑拆分为多个知识库

总结

📋一句话总结
Obsidian 以数据主权、非线性思考、高度可定制为核心,免费且跨平台,是构建个人知识体系的优秀工具。学习曲线虽存在,但掌握核心功能后即可快速搭建属于自己的知识管理系统。

AI时代,如何构建垂直领域的数据与知识壁垒

最近被各种 AI 技术与信息塞满了脑袋,说实话有点晕。从 GPT-4 到 DeepSeek 再到百家争鸣,从 FunctionCall、MCP、Skill 到 CLI,从 Ollama 到 OpenClaw,再到最近的 Harness Engineering 和 LLM Wiki——新词汇实在太多,已经记不住了。

但我始终坚信一件事:学习知识的方法、总结经验的思考,才是个人无法被 AI 替代的底子。 企业其实也一样。今天就想和大家聊聊,在这个 AI 时代,怎么在垂直领域里建立起真正属于自己的壁垒。


先聊一个核心认知

构建壁垒这件事,说到底就是把行业经验变成数字资产,再沉淀为智能优势的过程。它不是简单地收集一堆数据就完事了,而是一个系统性的工程——目的是打造竞争对手很难复制的东西。

我的思路可以拆成四层,一层一层往上垒:

层次 干什么 要达到什么效果
数据层 盘点与治理 把散乱的”原料”变成可用的”资产”
知识层 提炼与编码 把人脑子里的经验变成系统里的能力
进化层 闭环与迭代 让壁垒自己生长,越用越强
安全层 部署与防御 把护城河加宽加深

接下来展开聊聊每一层。


第一层:盘点与治理——别让数据只躺在那吃灰

有句话很扎心但很真实:未经治理的数据只是成本,不是资产。 你公司硬盘里躺着的那些数据,如果不经过整理和治理,它们就是纯支出——占存储、耗电、还有合规风险。

先摸清自己的家底

第一步是做一次彻底的数据盘点,拉出一份《数据资产清单》。别漏掉任何角落:

  • 结构化数据:ERP、CRM 里的那些数据库
  • 非结构化数据:各种报告、邮件、合同
  • 多媒体与 IoT 数据:监控录像、传感器日志、语音记录

然后搞清楚每份数据的归属部门和负责人,按《数据安全法》等法规做好敏感等级划分(公开 / 内部 / 机密),该脱敏脱敏、该加密加密。这一步虽然枯燥,但它是后面所有事情的地基。

找到你的”独家矿”

说实话,网上能爬到的公开数据,大家都能拿到,构不成壁垒。真正的护城河来自只有你才能获取的独家数据——我管它叫”母矿”:

行业 独家数据举例
工业 设备历史运行与维修记录
医疗 真实病例与手术记录
金融 独家投研报告与交易数据

这些数据别人没有,是你训练专属 AI 模型的根本,也是差异化优势的源头。

搭一个数据流转中枢

别让每个 AI 项目都自己去处理数据、重复造轮子。建一个统一的数据处理平台,负责所有数据的接入、清洗、质量校验和标准化。这样所有 AI 应用都基于同一套高质量、统一标准的数据来开发,效率提升是显而易见的。


第二层:提炼与编码——把老师傅的本事”写”进系统

数据本身不是壁垒。真正值钱的是数据里蕴含的行业 Know-how。这一层要做的事,就是把资深专家脑子里的经验、判断逻辑、决策框架”编码”进系统。

搭建领域知识图谱

一个行业里散落着大量非结构化的专业知识——法律条文、医疗指南、咨询方法论……把它们结构化,构建成知识图谱。

简单说就是定义”实体”和”关系”。比如医疗领域,”疾病”和”药品”之间有”治疗”关系,”药品”和”副作用”之间有”可能引发”关系。这样 AI 就不只是”看到”数据,而是能理解数据背后的专业逻辑和关联。

把专家的思考方式”固化”下来

每个行业都有那么一批顶尖专家,他们在处理复杂、模糊问题时有一套自己的思考路径和决策框架。找到他们,把这些框架提炼出来,转化为 AI Agent 可以遵循的工作流。

举个小例子:一个金融投研 Agent,如果它能模仿资深分析师的思考方式——动态地收集信息、分析财报、评估风险,最后输出的分析报告质量就能接近人类专家的水平。这就是把”人”的能力变成了”系统”的能力。

把专业能力打包成可复用的”技能”

合同审查、代码调试、设备故障诊断……这些特定的专业能力可以封装成独立的、可被 AI 调用的”技能模块”。好处是什么呢?它们可以像积木一样灵活组合,快速响应不同场景的需求,形成产品化的能力输出


第三层:闭环与迭代——让壁垒”自己长”

这里有个很重要的认知:静态的壁垒一定会被超越。 真正坚不可摧的壁垒,是那种能自我进化、越用越强的。

跑起来一个”数据飞轮”

AI Agent 在服务客户的过程中,会持续产生大量有价值的东西:新的交互数据、用户反馈、纠错记录……别让这些”实战数据”白白流失。

建立一套机制,把这些数据自动回传到数据中枢,用来持续优化模型、丰富知识图谱、迭代决策框架。

让它形成正向循环

更好的模型 → 更优质的服务 → 吸引更多客户 → 产生更多数据 → 模型变得更强 → ……

这个飞轮一旦转起来,后来者想要追赶就非常困难了。因为你的壁垒不是静态的,它在不断自我加强。


第四层:部署与防御——把护城河加宽

光建壁垒还不够,还得防着别人把它挖走。

能私有化就私有化

对金融、政务、大型制造这类对数据安全要求极高的客户,提供私有化部署方案。把 AI 模型和知识库直接部署在客户内网或本地服务器上,实现数据的物理隔离。客户不用担心数据泄露,你也守住了核心资产。

用”黑盒”策略保护核心逻辑

有时候不得不调用外部大模型,这时候要注意:敏感数据的计算和逻辑判断一定在自己的系统内完成,只把脱敏后的结论或简单指令发给外部模型。说白了就是——核心业务逻辑不能被外部模型”偷师”。

深度嵌入客户的日常

把你的 AI 解决方案深度嵌入到客户的核心业务流程里,让它成为日常运营中不可或缺的一部分。一旦做到这个程度,客户的迁移成本就会变得非常高,这本身就是一种强大的客户锁定效应。


写在最后

说了这么多,其实思路很清晰:数据治理 → 知识编码 → 闭环迭代 → 安全防御,四层递进,把无形的行业经验和数据,一步步转化为有形的、可迭代的、安全的智能壁垒。

AI 时代不缺通用的能力,缺的是深扎在某个领域里的、不可替代的东西。希望这篇文章能给你一些启发,也欢迎交流你的想法。

SAP AI 助手智能分析系统错误

💡本文背景
介绍 SAP ST22 事务码集成 SAP_AI助手的方法,实现运行时错误的智能分析,协助 BASIS 快速定位和解决问题。测试环境为 SAP ECC 6.0 EHP8,不同版本的隐式增强位置可能有差异,思路相同,自行 Debug 查找合适的增强点即可。

效果演示

集成后,在 ST22 的 ALV 列表中右键即可调用 SAP_AI助手,AI 会根据错误信息自动生成分析结果和解决建议,协助 BASIS 完成问题查询。

ST22 右键调用 SAP_AI助手 分析结果

DeepSeek AI 详细分析报告


程序实现

实现分为两个核心步骤:添加右键菜单触发事件调用 AI

步骤一:添加 ALV 右键菜单选项

在 ST22 的 ALV 框架中,利用类 CL_GUI_ALV_GRIDINIT_CONTEXT_MENU 方法,通过隐式增强添加自定义右键选项。

增强位置INIT_CONTEXT_MENU 方法(隐式增强)

INIT_CONTEXT_MENU 方法 Debug 定位

1
2
3
4
5
6
7
8
9
10
11
12
" 增加右键按钮:调用SAP_AI助手
IF SY-cprog = 'RSSHOWRABAX'.
"
READ TABLE it_toolbar_excluding INTO DATA(ls_toolbar_excluding)
WITH KEY table_line = '&ZAIAS'.
IF sy-subrc NE 0.
CALL METHOD m_cl_context_menu->add_function
EXPORTING
fcode = '&ZAIAS'
text = text-m03. " 访问DeepSeek平台
ENDIF.
ENDIF.

隐式增强添加右键菜单代码

ℹ️关键点
  • SY-cprog = 'RSSHOWRABAX' 确保仅在 ST22 程序中生效
  • &ZAIAS 为自定义 FCODE,需避免与标准功能冲突
  • text-m03 为文本元素,内容为”调用SAP_AI助手”

步骤二:添加菜单触发事件

EXECUTE_FCODE 方法中通过隐式增强,添加 &ZAIAS 的触发逻辑:获取当前行的错误信息,构造 Prompt,调用 AI 程序。

增强位置EXECUTE_FCODE 方法(隐式增强)

EXECUTE_FCODE 隐式增强实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
WHEN '&ZAIAS'.
" 取得光标位置
CALL METHOD me->get_current_cell
IMPORTING es_row_no = DATA(ls_row_no).

" 取得错误信息(第7列)
READ TABLE mt_data INTO DATA(ls_error)
WITH KEY row_pos = ls_row_no-row_id
col_pos = 7.
IF sy-subrc <> 0.
CLEAR ls_error.
ENDIF.

" 取得例外信息(第8列)
READ TABLE mt_data INTO DATA(ls_exception)
WITH KEY row_pos = ls_row_no-row_id
col_pos = 8.
IF sy-subrc <> 0.
CLEAR ls_exception.
ENDIF.

" 取得程序信息(第9列)
READ TABLE mt_data INTO DATA(ls_report)
WITH KEY row_pos = ls_row_no-row_id
col_pos = 9.
IF sy-subrc <> 0.
CLEAR ls_report.
ENDIF.

" 构造AI提示词
DATA(lv_prompt) =
|我是一个SAP顾问,目前在SAP GUI系统,|
& |SAP BASIS Component为755,操作系统为Linux,|
& |数据库为HDB,Schema为SAPHANADB,|
& |正在使用事务码ST22查询系统错误,|
& |运行时错误为{ ls_error-value },|
& |例外为{ ls_exception-value },|
& |已取消程序为{ ls_report-value },|
& |请帮我分析这个错误发生的原因,并告诉我应该怎么处理该问题?|.

" 调用已开发好的SAP_AI助手程序
SUBMIT zidtr_ai_assistant AND RETURN
WITH p_r15 = abap_true
WITH p_prompt = lv_prompt.
⚠️注意事项
  • col_pos 值对应 ALV 列的位置,如果 ST22 的 ALV 结构发生变化需要调整
  • zidtr_ai_assistant 程序需提前开发完成(参见 SAP 集成 SAP_AI助手程序调用 API 章节)

实现原理总结



flowchart LR
    A[ST22 ALV 右键] --> B["选择 '调用SAP_AI助手'"]
    B --> C[读取当前行错误/例外/程序]
    C --> D[构造 Prompt]
    D --> E["SUBMIT zidtr_ai_assistant"]
    E --> F[调用 DeepSeek API]
    F --> G[返回分析结果]

📋核心思路
  1. 通过 隐式增强 在标准 ALV 框架中注入自定义菜单和行为
  2. 读取 ALV 当前行的关键字段(错误、例外、程序名)
  3. 拼装上下文 Prompt,调用独立的 SAP_AI助手程序完成分析
  4. 该模式可复用到其他需要 AI 辅助分析的事务码场景
0%