#!/bin/bash
# 基础配置
SRC_DIR=/data/HH-Cloud # 源码路径
WORK_DIR=/data/jar # 工作目录
LOG_DIR=/data/logs # 日志目录
# 服务脚本列表
SERVICE_SCRIPTS=(
"hh-gateway"
"hh-auth"
"hh-xxl-job-admin"
"hh-trade"
"hh-system"
"hh-site"
"hh-sign"
"hh-sentinel-dashboard"
"hh-resource"
"hh-monitor"
"hh-mall"
"hh-job"
"hh-im"
"hh-finance"
)
# Nacos、RocketMQ 和 Seata 启动和停止脚本
NACOS_START_CMD="bash /data/nacos/bin/startup.sh -m standalone"
NACOS_STOP_CMD="bash /data/nacos/bin/shutdown.sh"
ROCKETMQ_START_CMD="nohup sh /data/rocketmq-5.2.0/bin/mqnamesrv > /data/logs/rocketmq_namesrv.log 2>&1 &"
ROCKETMQ_BROKER_CMD="nohup sh /data/rocketmq-5.2.0/bin/mqbroker -n 127.0.0.1:9876 > /data/logs/rocketmq_broker.log 2>&1 &"
ROCKETMQ_STOP_CMD="sh /data/rocketmq-5.2.0/bin/mqshutdown namesrv && sh /data/rocketmq-5.2.0/bin/mqshutdown broker"
SEATA_START_CMD=" bash /data/seata-server-1.6.0/bin/seata-server.sh &"
SEATA_STOP_CMD="bash /data/seata-server-1.6.0/bin/seata-server.sh stop"
OPTIONS="-Xms512m -Xmx512m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
# 确保目录存在
mkdir -p $WORK_DIR
mkdir -p $LOG_DIR
# 启动单个服务
start_service() {
local SERVICE=$1
local JAR_PATH=""
local LOG_FILE=$LOG_DIR/$SERVICE.log
local PID_FILE=/var/run/$SERVICE.pid
echo "Starting $SERVICE..."
# 查找 JAR 文件
for DIR in "$SRC_DIR/hh-gateway/target" "$SRC_DIR/hh-modules/$SERVICE/target" "$SRC_DIR/hh-visual/$SERVICE/target" "$SRC_DIR/hh-auth/target"; do
if [ -f "$DIR/$SERVICE.jar" ]; then
JAR_PATH="$DIR/$SERVICE.jar"
break
fi
done
if [ -z "$JAR_PATH" ]; then
echo "Error: JAR file for $SERVICE not found!"
return
fi
# 检查是否已在运行
if [ -f $PID_FILE ]; then
PID=$(cat $PID_FILE)
if kill -0 $PID 2>/dev/null; then
echo "$SERVICE is already running (PID: $PID)"
return
else
echo "Stale PID file found for $SERVICE. Removing it."
rm -f $PID_FILE
fi
fi
# 停止旧进程(如果未正确停止)
OLD_PID=$(ps -ef | grep "$SERVICE".jar | grep -v grep | awk '{print $2}')
if [ -n "$OLD_PID" ]; then
echo "Stopping old instance of $SERVICE (PID: $OLD_PID)..."
kill -9 $OLD_PID
echo "Old instance stopped."
fi
# 启动新服务
nohup java $OPTIONS -jar $JAR_PATH --spring.profiles.active=stage > $LOG_FILE 2>&1 &
NEW_PID=$!
echo $NEW_PID > $PID_FILE
echo "$SERVICE started (PID: $NEW_PID)"
}
# 停止单个服务
stop_service() {
local SERVICE=$1
local PID_FILE=/var/run/$SERVICE.pid
echo "Stopping $SERVICE..."
if [ -f $PID_FILE ]; then
PID=$(cat $PID_FILE)
if kill -0 $PID 2>/dev/null; then
kill -9 $PID
rm -f $PID_FILE
echo "$SERVICE stopped."
else
echo "PID $PID not valid. Removing stale PID file."
rm -f $PID_FILE
fi
else
echo "$SERVICE is not running."
fi
}
# 查询单个服务状态
status_service() {
local SERVICE=$1
local PID_FILE=/var/run/$SERVICE.pid
if [ -f $PID_FILE ] && kill -0 $(cat $PID_FILE) 2>/dev/null; then
echo "$SERVICE is running (PID: $(cat $PID_FILE))"
else
echo "$SERVICE is not running."
fi
}
# 启动 Nacos、RocketMQ、Seata 服务
start_nacos() {
echo "Starting Nacos..."
$NACOS_START_CMD &
echo "Nacos started."
}
start_rocketmq() {
echo "Starting RocketMQ..."
# 启动 NameServer
eval $ROCKETMQ_START_CMD
sleep 2 # 稍等一下,确保 NameServer 启动
# 启动 Broker
eval $ROCKETMQ_BROKER_CMD
sleep 2 # 稍等一下,确保 Broker 启动
# 使用 disown 完全将进程与终端分离
disown
echo "RocketMQ started. Logs are available in /data/logs/rocketmq_namesrv.log and /data/logs/rocketmq_broker.log"
}
start_seata() {
echo "Starting Seata..."
$SEATA_START_CMD
sleep 3 # 给 Seata 一些时间启动
echo "Seata started."
}
# 停止 Nacos、RocketMQ、Seata 服务
stop_nacos() {
echo "Stopping Nacos..."
$NACOS_STOP_CMD
echo "Nacos stopped."
}
stop_rocketmq() {
echo "Stopping RocketMQ..."
$ROCKETMQ_STOP_CMD
echo "RocketMQ stopped."
}
stop_seata() {
echo "Stopping Seata..."
$SEATA_STOP_CMD
echo "Seata stopped."
}
# 检查参数
if [ $# -ne 1 ]; then
echo "Usage: $0 <start|stop|status>"
exit 1
fi
ACTION=$1
# 根据参数执行操作
case $ACTION in
start)
# 启动所有服务
start_nacos
start_rocketmq
start_seata
for SERVICE in "${SERVICE_SCRIPTS[@]}"; do
start_service $SERVICE
sleep 2 # 确保每个服务有足够时间启动
done
echo "All services started."
;;
stop)
# 停止所有服务
stop_nacos
stop_rocketmq
stop_seata
for SERVICE in "${SERVICE_SCRIPTS[@]}"; do
stop_service $SERVICE
done
echo "All services stopped."
;;
status)
# 检查所有服务状态
echo "Checking Nacos status..."
status_service nacos
echo "Checking RocketMQ status..."
status_service rocketmq
echo "Checking Seata status..."
status_service seata
for SERVICE in "${SERVICE_SCRIPTS[@]}"; do
status_service $SERVICE
done
;;
*)
echo "Invalid action: $ACTION. Use 'start', 'stop', or 'status'."
exit 1
;;
esac
微信小程序和H5端对接dify ai接口
用的uniapp开发的
H5端是基于SSE协议开发的
要安装
import {
fetchEventSource
} from '@microsoft/fetch-event-source';
/*#ifdef H5*/
const eventSource = new fetchEventSource('/v1/chat-messages', {
method: 'POST',
headers: {
'Authorization': 'Bearer app-xxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({
inputs: {},
query: message, // 替换为实际的查询内容
response_mode: 'streaming', // 启用流式响应
conversation_id: that.conversationId,
user: "abc-123"
}),
onopen(response) {
// 建立连接
console.log(response, "open");
if (response.ok) {
console.log("成功建立连接");
} else {
throw new Error(JSON.stringify(response));
}
},
onmessage(event) {
try {
const jsonData = JSON.parse(event.data);
if (jsonData.event === "message") {
//that.loading = false; // 隐藏加载图标
that.conversationId = jsonData.conversation_id;
// 如果返回的答案中有新的文字,逐字显示
if (jsonData.answer) {
// 追加接收到的新文字
that.displayedText += jsonData.answer;
// 继续显示新的文字
//that.startTyping(jsonData.message_id);
}
}
console.log("that.displayedText", that.displayedText);
if (jsonData.event === "message_end") {
that.loading = false; // 隐藏加载图标
that.arr.push({
answer: that.displayedText,
message_id: jsonData.message_id,
});
that.displayedText = "";
console.log("that.arr", that.arr);
}
} catch (error) {
console.error("数据解析错误:", error);
}
},
onclose() {
console.log("关闭链接");
},
onerror(err) {
console.error("发生错误", err);
throw err;
},
openWhenHidden: true, // 实时通知
});
/*#endif*/
/*#ifdef MP-WEIXIN*/
// 微信小程序端执行的逻辑
const requestTask = uni.request({
url: '/v1/chat-messages',
timeout: 15000,
responseType: 'text',
method: 'POST',
header: {
'Authorization': 'Bearer app-xxx',
'Content-Type': 'application/json',
},
enableChunked: true, //配置这里
data: JSON.stringify({
inputs: {},
query: message, // 替换为实际的查询内容
response_mode: 'streaming', // 启用流式响应
conversation_id: that.conversationId,
user: "abc-123"
}),
success: response => {
console.log(response)
},
fail: error => {}
})
requestTask.onHeadersReceived(function(res) {
console.log(res.header);
});
// 这里监听消息
requestTask.onChunkReceived(function(res) {
let decoder = new TextDecoder('utf-8')
let text = decoder.decode(new Uint8Array(res.data))
console.log(text)
try {
// 使用正则表达式去除前缀 "data: "
const jsonString = text.replace(/^data:\s*/, '');
const jsonData = JSON.parse(jsonString);
if (jsonData.event === "message") {
//that.loading = false; // 隐藏加载图标
that.conversationId = jsonData.conversation_id;
// 如果返回的答案中有新的文字,逐字显示
if (jsonData.answer) {
// 追加接收到的新文字
that.displayedText += jsonData.answer;
// 继续显示新的文字
//that.startTyping(jsonData.message_id);
}
}
console.log("that.displayedText", that.displayedText);
if (jsonData.event === "message_end") {
that.loading = false; // 隐藏加载图标
that.arr.push({
answer: that.displayedText,
message_id: jsonData.message_id,
});
that.displayedText = "";
console.log("that.arr", that.arr);
}
} catch (error) {
console.error("数据解析错误:", error);
}
})
/*#endif*/
目录
- 拉取镜像
- 创建挂载点目录
- 创建minio容器
- 启动minio容器
测试minio是否安装成功
minio官网:MinIO | High Performance, Kubernetes Native Object Storage
拉取镜像
代码:
docker pull minio/minio
实例:
[root@localhost howlong]# docker pull minio/minio Using default tag: latest latest: Pulling from minio/minio 5329d7039f25: Pull complete 2b3707fd3b24: Pull complete 5206d1e7147f: Pull complete 33feab5fa1c5: Pull complete 5cd9e0eb62e5: Pull complete 34f92c74bdaf: Pull complete Digest: sha256:15d762671436cf383f9cc6667260e6c1298c25c8d7009576f709c3823e4a494d Status: Downloaded newer image for minio/minio:latest docker.io/minio/minio:latest [root@localhost howlong]#
创建挂载点目录
代码:
mkdir -p /usr/local/minio/config mkdir -p /usr/local/minio/data
创建minio容器
注意:这里设置了minio客户端的账号和密码,其密码不可少于8位 账号:admin 密码:admin123
代码:
docker run -d \ --name minio \ -p 9000:9000 \ -p 9001:9001 \ --privileged=true \ -e "MINIO_ROOT_USER=admin" \ -e "MINIO_ROOT_PASSWORD=admin123" \ -v /usr/local/minion/data:/data \ -v /usr/local/minio/config:/root/.minio \ minio/minio server \ --console-address ":9000" \ --address ":9001" /data
实例:
[root@localhost howlong]# docker run -d \ --name minio \ -p 9000:9000 \ -p 9001:9001 \ --privileged=true \ -e "MINIO_ROOT_USER=admin" \ -e "MINIO_ROOT_PASSWORD=admin123" \ -v /usr/local/minion/data:/data \ -v /usr/local/minio/config:/root/.minio \ minio/minio server \ --console-address ":9000" \ --address ":9001" /data 93c98998d5cbc51c6f208cfe676adf495d4931469aad1d9756e19dca3fd4b66a
启动minio容器
代码:
docker start minio
实例:
[root@localhost howlong]# docker start minio minio [root@localhost howlong]#
测试minio是否安装成功
访问虚拟机地址+端口号,前面配置minio 的端口号为:9000
例如:
账号:admin 密码:admin123
1、寻找Nginx镜像
2、下载Nginx镜像
命令 描述
docker pull nginx 下载最新版Nginx镜像 (其实此命令就等同于 : docker pull nginx:latest )
docker pull nginx:xxx 下载指定版本的Nginx镜像 (xxx指具体版本号)
检查当前所有Docker下载的镜像
docker images
3、创建Nginx配置文件
启动前需要先创建Nginx外部挂载的配置文件( /home/nginx/conf/nginx.conf)
之所以要先创建 , 是因为Nginx本身容器只存在/etc/nginx 目录 , 本身就不创建 nginx.conf 文件
当服务器和容器都不存在 nginx.conf 文件时, 执行启动命令的时候 docker会将nginx.conf 作为目录创建 , 这并不是我们想要的结果 。
# 创建挂载目录
mkdir -p /home/nginx/conf
mkdir -p /home/nginx/log
mkdir -p /home/nginx/html
容器中的nginx.conf文件和conf.d文件夹复制到宿主机
# 生成容器
docker run --name nginx -p 9001:80 -d nginx
# 将容器nginx.conf文件复制到宿主机
docker cp nginx:/etc/nginx/nginx.conf /home/nginx/conf/nginx.conf
# 将容器conf.d文件夹下内容复制到宿主机
docker cp nginx:/etc/nginx/conf.d /home/nginx/conf/conf.d
# 将容器中的html文件夹复制到宿主机
docker cp nginx:/usr/share/nginx/html /home/nginx/
4、创建Nginx容器并运行
Docker 创建Nginx容器
# 直接执行docker rm nginx或者以容器id方式关闭容器
# 找到nginx对应的容器id
docker ps -a
# 关闭该容器
docker stop nginx
# 删除该容器
docker rm nginx
# 删除正在运行的nginx容器
docker rm -f nginx
docker run \
-p 9002:80 \
--name nginx \
-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /home/nginx/conf/conf.d:/etc/nginx/conf.d \
-v /home/nginx/log:/var/log/nginx \
-v /home/nginx/html:/usr/share/nginx/html \
-d nginx:latest
命令 描述
–name nginx 启动容器的名字
-d 后台运行
-p 9002:80 将容器的 9002(后面那个) 端口映射到主机的 80(前面那个) 端口
-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf 挂载nginx.conf配置文件
-v /home/nginx/conf/conf.d:/etc/nginx/conf.d 挂载nginx配置文件
-v /home/nginx/log:/var/log/nginx 挂载nginx日志文件
-v /home/nginx/html:/usr/share/nginx/html 挂载nginx内容
nginx:latest 本地运行的版本
\ shell 命令换行
单行模式
docker run -p 9002:80 --name nginx -v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf -v /home/nginx/conf/conf.d:/etc/nginx/conf.d -v /home/nginx/log:/var/log/nginx -v /home/nginx/html:/usr/share/nginx/html -d nginx:latest
5、结果检测
6、修改内容进行展示
# 重启容器
docker restart nginx
此错误是因为没有授权给admin用户对system数据库执行命令的权限,解决方法如下:
db.grantRolesToUser ( "用户名", [ { role: "__system", db: "admin" } ] )