diff --git a/consul/config/consul.hcl b/consul/config/consul.hcl index 508eec9..144ebe0 100644 --- a/consul/config/consul.hcl +++ b/consul/config/consul.hcl @@ -3,6 +3,6 @@ ui_config { } acl { - enabled = true + enabled = false default_policy = "deny" } \ No newline at end of file diff --git a/consul/config/data-service.hcl b/consul/config/data-service.hcl new file mode 100644 index 0000000..a9139a5 --- /dev/null +++ b/consul/config/data-service.hcl @@ -0,0 +1,17 @@ +service { + name = "data-service" + id = "data-service-1" + address = "data-service" + port = 8000 + + check { + http = "http://aktools:8080/quote_zh_a_hist?symbol=sh600000&period=daily&start_date=20220101&end_date=20220102" + interval = "10s" + timeout = "5s" + } + + meta = { + "traefik.enable" = "true" + "traefik.http.routers.data-service.rule" = "PathPrefix(`/api/data`)" + } +} \ No newline at end of file diff --git a/consul/config/emotion-service.hcl b/consul/config/emotion-service.hcl new file mode 100644 index 0000000..996e90c --- /dev/null +++ b/consul/config/emotion-service.hcl @@ -0,0 +1,17 @@ +service { + name = "emotion-service" + id = "emotion-service-1" + address = "emotion-service" + port = 8002 + + check { + http = "http://emotion-service:8002/health" + interval = "10s" + timeout = "5s" + } + + meta = { + "traefik.enable" = "true" + "traefik.http.routers.emotion-service.rule" = "PathPrefix(`/api/emotion`)" + } +} \ No newline at end of file diff --git a/consul/config/frontend.hcl b/consul/config/frontend.hcl new file mode 100644 index 0000000..d1d3a99 --- /dev/null +++ b/consul/config/frontend.hcl @@ -0,0 +1,17 @@ +service { + name = "frontend" + id = "frontend-1" + address = "frontend" + port = 80 + + check { + http = "http://frontend:80/" + interval = "10s" + timeout = "5s" + } + + meta = { + "traefik.enable" = "true" + "traefik.http.routers.frontend.rule" = "PathPrefix(`/`)" + } +} \ No newline at end of file diff --git a/consul/config/quant-service.hcl b/consul/config/quant-service.hcl new file mode 100644 index 0000000..d71927c --- /dev/null +++ b/consul/config/quant-service.hcl @@ -0,0 +1,17 @@ +service { + name = "quant-service" + id = "quant-service-1" + address = "quant-service" + port = 8001 + + check { + http = "http://quant-service:8001/health" + interval = "10s" + timeout = "5s" + } + + meta = { + "traefik.enable" = "true" + "traefik.http.routers.quant-service.rule" = "PathPrefix(`/api/quant`)" + } +} \ No newline at end of file diff --git a/consul/config/recommend-service.hcl b/consul/config/recommend-service.hcl new file mode 100644 index 0000000..5ef6ed1 --- /dev/null +++ b/consul/config/recommend-service.hcl @@ -0,0 +1,17 @@ +service { + name = "recommend-service" + id = "recommend-service-1" + address = "recommend-service" + port = 8003 + + check { + http = "http://recommend-service:8003/health" + interval = "10s" + timeout = "5s" + } + + meta = { + "traefik.enable" = "true" + "traefik.http.routers.recommend-service.rule" = "PathPrefix(`/api/recommend`)" + } +} \ No newline at end of file diff --git a/consul/config/user-service.hcl b/consul/config/user-service.hcl new file mode 100644 index 0000000..7269865 --- /dev/null +++ b/consul/config/user-service.hcl @@ -0,0 +1,17 @@ +service { + name = "user-service" + id = "user-service-1" + address = "user-service" + port = 8004 + + check { + http = "http://user-service:8004/health" + interval = "10s" + timeout = "5s" + } + + meta = { + "traefik.enable" = "true" + "traefik.http.routers.user-service.rule" = "PathPrefix(`/api/user`)" + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index a75397a..501f721 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,78 +1,138 @@ version: '3.8' + +networks: + microservice-network: + driver: bridge + services: + consul: + image: consul:1.15 + container_name: ari-consul + restart: always + ports: + - "8500:8500" # Consul Web UI + - "8600:8600/udp" # DNS服务 + volumes: + - ./consul/config:/consul/config + command: "consul agent -dev -config-dir=/consul/config -client=0.0.0.0" + networks: + - microservice-network + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8500/v1/status/leader"] + interval: 10s + timeout: 5s + retries: 3 + traefik: image: traefik:v2.9 - command: - - --entrypoints.web.address=:80 - - --providers.consulcatalog=true - - --providers.consulcatalog.endpoint.address=consul:8500 - - --api.dashboard=true + container_name: ari-traefik + restart: always + depends_on: + consul: + condition: service_healthy ports: - - "80:80" + - "80:80" # 主入口 + - "8080:8080" # Dashboard volumes: - ./traefik/traefik.yml:/etc/traefik/traefik.yml - - /var/run/docker.sock:/var/run/docker.sock + - /var/run/docker.sock:/var/run/docker.sock:ro + command: + - --providers.consulcatalog=true + - --providers.consulcatalog.endpoint.address=consul:8500 + - --providers.consulcatalog.exposedbydefault=false + - --api.dashboard=true + - --log.level=INFO + networks: + - microservice-network labels: - "traefik.enable=true" + - "traefik.http.routers.traefik-dashboard.rule=PathPrefix(`/dashboard`) || PathPrefix(`/api`)" + - "traefik.http.routers.traefik-dashboard.service=api@internal" + - "traefik.http.routers.traefik-dashboard.entrypoints=web" data-service: build: ./services/data-service - labels: - - "traefik.enable=true" - - "traefik.http.routers.data.rule=PathPrefix(`/api/data`)" + container_name: ari-data-service + restart: always + depends_on: + consul: + condition: service_healthy expose: - "8000" + networks: + - microservice-network + environment: + - SERVICE_NAME=data-service quant-service: build: ./services/quant-service - labels: - - "traefik.enable=true" - - "traefik.http.routers.quant.rule=PathPrefix(`/api/quant`)" + container_name: ari-quant-service + restart: always + depends_on: + consul: + condition: service_healthy expose: - "8001" + networks: + - microservice-network + environment: + - SERVICE_NAME=quant-service emotion-service: build: ./services/emotion-service - labels: - - "traefik.enable=true" - - "traefik.http.routers.emotion.rule=PathPrefix(`/api/emotion`)" + container_name: ari-emotion-service + restart: always + depends_on: + consul: + condition: service_healthy expose: - "8002" + networks: + - microservice-network + environment: + - SERVICE_NAME=emotion-service recommend-service: build: ./services/recommend-service - labels: - - "traefik.enable=true" - - "traefik.http.routers.recommend.rule=PathPrefix(`/api/recommend`)" + container_name: ari-recommend-service + restart: always + depends_on: + consul: + condition: service_healthy expose: - "8003" + networks: + - microservice-network + environment: + - SERVICE_NAME=recommend-service user-service: build: ./services/user-service - labels: - - "traefik.enable=true" - - "traefik.http.routers.user.rule=PathPrefix(`/api/user`)" + container_name: ari-user-service + restart: always + depends_on: + consul: + condition: service_healthy expose: - "8004" + networks: + - microservice-network + environment: + - SERVICE_NAME=user-service frontend: build: ./services/frontend - labels: - - "traefik.enable=true" - - "traefik.http.routers.frontend.rule=PathPrefix(`/`)" + container_name: ari-frontend + restart: always + depends_on: + - data-service + - quant-service + - emotion-service + - recommend-service + - user-service expose: - "80" - - gitea-webhook: - build: ./gitea-webhook - ports: - - "5005:5005" - - consul: - image: consul:1.15 - ports: - - "8500:8500" # Consul Web UI - - "8600:8600/udp" - volumes: - - ./consul/config:/consul/config - command: "consul agent -dev -config-dir=/consul/config" + networks: + - microservice-network + environment: + - SERVICE_NAME=frontend \ No newline at end of file diff --git a/services/data-service/Dockerfile b/services/data-service/Dockerfile index 684ec1c..e688798 100644 --- a/services/data-service/Dockerfile +++ b/services/data-service/Dockerfile @@ -4,4 +4,4 @@ WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . -CMD ["sh", "-c", "aktools run --port 8001 & python register.py && wait"] +CMD ["python", "-m", "aktools", "--host", "0.0.0.0", "--port", "8000"] diff --git a/services/data-service/app.py b/services/data-service/app.py deleted file mode 100644 index 00a450b..0000000 --- a/services/data-service/app.py +++ /dev/null @@ -1,19 +0,0 @@ -from flask import Flask, jsonify -import threading -import subprocess -from register import register_to_consul - -app = Flask(__name__) - -@app.route("/health") -def health(): - return jsonify({"status": "ok"}), 200 - -@app.route("/hello") -def hello(): - return jsonify({"message": "Hello from service!"}) - -if __name__ == "__main__": - threading.Thread(target=register_to_consul).start() - subprocess.Popen(["aktools", "run", "--port", "8001"]) - app.run(host="0.0.0.0", port=8000) diff --git a/services/data-service/register.py b/services/data-service/register.py deleted file mode 100644 index c926e99..0000000 --- a/services/data-service/register.py +++ /dev/null @@ -1,27 +0,0 @@ -import time -import requests - -def register_to_consul(): - time.sleep(3) # 等待服务稳定再注册 - service_name = "aktools-service" # AKTools 主服务 - port = 8001 # AKTools 端口 - - payload = { - "Name": service_name, - "ID": f"{service_name}-1", - "Address": service_name, # 容器名作为地址 - "Port": port, - "Check": { - "TCP": f"{service_name}:{port}", - "Interval": "10s" - } - } - - try: - requests.put("http://consul:8500/v1/agent/service/register", json=payload) - print(f"[{service_name}] Registered to Consul") - except Exception as e: - print(f"❌ Consul register failed: {e}") - -if __name__ == "__main__": - register_to_consul() diff --git a/services/data-service/requirements.txt b/services/data-service/requirements.txt index aa2ae89..6ef13ae 100644 --- a/services/data-service/requirements.txt +++ b/services/data-service/requirements.txt @@ -1,2 +1 @@ -flask aktools \ No newline at end of file diff --git a/services/emotion-service/app.py b/services/emotion-service/app.py index 29b1ae8..206e269 100644 --- a/services/emotion-service/app.py +++ b/services/emotion-service/app.py @@ -1,6 +1,5 @@ from flask import Flask, jsonify import threading -from register import register_to_consul app = Flask(__name__) @@ -13,5 +12,4 @@ def hello(): return jsonify({"message": "Hello from service!"}) if __name__ == "__main__": - threading.Thread(target=register_to_consul).start() app.run(host="0.0.0.0", port=8002) diff --git a/services/emotion-service/register.py b/services/emotion-service/register.py deleted file mode 100644 index 310324c..0000000 --- a/services/emotion-service/register.py +++ /dev/null @@ -1,24 +0,0 @@ -import time -import requests - -def register_to_consul(): - time.sleep(3) # 等待服务稳定再注册 - service_name = "emotion-service" # 替换为 quant-service/emotion-service 等 - port = 8002 # 替换为 8001, 8002 等 - - payload = { - "Name": service_name, - "ID": f"{service_name}-1", - "Address": service_name, # 容器名作为地址 - "Port": port, - "Check": { - "HTTP": f"http://{service_name}:{port}/health", - "Interval": "10s" - } - } - - try: - requests.put("http://consul:8500/v1/agent/service/register", json=payload) - print(f"[{service_name}] Registered to Consul") - except Exception as e: - print(f"❌ Consul register failed: {e}") diff --git a/services/quant-service/app.py b/services/quant-service/app.py index e672de8..07eaa6b 100644 --- a/services/quant-service/app.py +++ b/services/quant-service/app.py @@ -1,6 +1,5 @@ from flask import Flask, jsonify import threading -from register import register_to_consul app = Flask(__name__) @@ -13,5 +12,4 @@ def hello(): return jsonify({"message": "Hello from service!"}) if __name__ == "__main__": - threading.Thread(target=register_to_consul).start() app.run(host="0.0.0.0", port=8001) diff --git a/services/quant-service/register.py b/services/quant-service/register.py deleted file mode 100644 index dea2549..0000000 --- a/services/quant-service/register.py +++ /dev/null @@ -1,24 +0,0 @@ -import time -import requests - -def register_to_consul(): - time.sleep(3) # 等待服务稳定再注册 - service_name = "quant-service" # 替换为 quant-service/emotion-service 等 - port = 8001 # 替换为 8001, 8002 等 - - payload = { - "Name": service_name, - "ID": f"{service_name}-1", - "Address": service_name, # 容器名作为地址 - "Port": port, - "Check": { - "HTTP": f"http://{service_name}:{port}/health", - "Interval": "10s" - } - } - - try: - requests.put("http://consul:8500/v1/agent/service/register", json=payload) - print(f"[{service_name}] Registered to Consul") - except Exception as e: - print(f"❌ Consul register failed: {e}") diff --git a/services/recommend-service/Program.cs b/services/recommend-service/Program.cs index 43b8a29..d3cad5a 100644 --- a/services/recommend-service/Program.cs +++ b/services/recommend-service/Program.cs @@ -4,4 +4,5 @@ using Microsoft.Extensions.Hosting; var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => new { service = "recommend-service", status = "ok" }); +app.MapGet("/health", () => new { status = "ok" }); app.Run("http://0.0.0.0:8003"); \ No newline at end of file diff --git a/services/user-service/Program.cs b/services/user-service/Program.cs index 7058efe..1de5be9 100644 --- a/services/user-service/Program.cs +++ b/services/user-service/Program.cs @@ -4,4 +4,5 @@ using Microsoft.Extensions.Hosting; var builder = WebApplication.CreateBuilder(args); var app = builder.Build(); app.MapGet("/", () => new { service = "user-service", status = "ok" }); +app.MapGet("/health", () => new { status = "ok" }); app.Run("http://0.0.0.0:8004"); \ No newline at end of file