.net core微服务之网关

网关:

一:apisix

doc:https://apisix.apache.org/zh/docs/apisix/getting-started/README/

github:https://github.com/apache/apisix

二:Kong

github:https://github.com/Kong/kong

三:Ocelot

github:https://github.com/ThreeMammals/Ocelot

四:janus

github:https://github.com/motiv-labs/janus

前置条件:docker,yaml

microservice.yaml

复制代码
version: "3.8"
networks:
  caseor_bridge:
    driver: bridge
    ipam:
      config:
        - subnet: 172.0.10.0/24
  
services:

    mysql:
        container_name: mysql
        image: mysql
        privileged: true
        command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --max_connections=2000 --max_allowed_packet=64M
        environment:
          - TZ=Asia/Shanghai
          - MYSQL_ROOT_PASSWORD=123456
        volumes:
          - ./mysql:/var/lib/mysql
        ports:
          - "3306:3306"
        healthcheck:
          test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
          interval: 5s
          timeout: 10s
          retries: 10
        networks:
          caseor_bridge:
            ipv4_address: 172.0.10.3

    redis:
        image: redis
        container_name: "redis"
        ports:
            - "6379:6379"
        volumes:
            - ./redis/data:/data
            - ./redis/conf:/usr/local/etc/redis
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.4

    nacos1:
        container_name: nacos1
        hostname: nacos1
        image: nacos/nacos-server
        environment:
            - MODE=cluster
            - PREFER_HOST_MODE=hostname
            - NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
            - SPRING_DATASOURCE_PLATFORM=mysql
            - MYSQL_SERVICE_HOST=172.0.10.3
            - MYSQL_SERVICE_PORT=3306
            - MYSQL_SERVICE_USER=root
            - MYSQL_SERVICE_PASSWORD=123456
            - MYSQL_SERVICE_DB_NAME=nacos
            - MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true  
            - JVM_XMS=128m
            - JVM_XMX=128m
            - JVM_XMN=128m
        volumes: 
            - ./nacos/cluster-logs/nacos1:/home/nacos/logs
            - ./nacos/init.d:/home/nacos/init.d
        ports: 
            - 8850:8848
            - 7850:7848     
            - 9870:9848
            - 9852:9849
        depends_on:
          - mysql
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.5

    nacos2:
        container_name: nacos2
        hostname: nacos2
        image: nacos/nacos-server
        environment:             
            - MODE=cluster
            - PREFER_HOST_MODE=hostname
            - NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
            - SPRING_DATASOURCE_PLATFORM=mysql
            - MYSQL_SERVICE_HOST=172.0.10.3
            - MYSQL_SERVICE_PORT=3306
            - MYSQL_SERVICE_USER=root
            - MYSQL_SERVICE_PASSWORD=123456
            - MYSQL_SERVICE_DB_NAME=nacos
            - MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true  
            - JVM_XMS=128m
            - JVM_XMX=128m
            - JVM_XMN=128m
        volumes: 
            - ./nacos/cluster-logs/nacos2:/home/nacos/logs
            - ./nacos/init.d:/home/nacos/init.d
        ports: 
            - 8849:8848
            - 7849:7848     
            - 9869:9848
            - 9851:9849
        depends_on:
          - mysql
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.6

    nacos3:
        container_name: nacos3
        hostname: nacos3
        image: nacos/nacos-server
        environment:             
            - MODE=cluster
            - PREFER_HOST_MODE=hostname
            - NACOS_SERVERS=nacos1:8848 nacos2:8848 nacos3:8848
            - SPRING_DATASOURCE_PLATFORM=mysql
            - MYSQL_SERVICE_HOST=172.0.10.3
            - MYSQL_SERVICE_PORT=3306
            - MYSQL_SERVICE_USER=root
            - MYSQL_SERVICE_PASSWORD=123456
            - MYSQL_SERVICE_DB_NAME=nacos
            - MYSQL_SERVICE_DB_PARAM=characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true  
            - JVM_XMS=128m
            - JVM_XMX=128m
            - JVM_XMN=128m
        volumes: 
            - ./nacos/cluster-logs/nacos3:/home/nacos/logs
            - ./nacos/init.d:/home/nacos/init.d
        ports: 
            - 8848:8848
            - 7848:7848     
            - 9848:9848
            - 9849:9849
        depends_on:
          - mysql
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.7

    etcd:
        container_name: etcd
        hostname: etcd
        image: bitnami/etcd
        volumes:
          - ./etcd/data:/bitnami/etcd
        environment:
          ETCD_ENABLE_V2: "true"
          ALLOW_NONE_AUTHENTICATION: "yes"
          ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379" #https://github.com/apache/apisix-dashboard/issues/2756 需要更换为host域名不能使用0.0.0.0
          ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
        ports:
          - "2379:2379/tcp"
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.8

    apisix:
        container_name: apisix
        hostname: apisix
        image: apache/apisix        
        volumes:
          - ./apisix/log:/usr/local/apisix/logs
          - ./apisix/conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
        depends_on:
          - etcd
        ports:
          - "9088:9088/tcp"
          - "9180:9180/tcp"
          - "127.0.0.1:9090:9090/tcp"
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.9
    
    apisix-dashboard:
        container_name: apisix-dashboard
        image: apache/apisix-dashboard
        depends_on:
          - etcd
        ports:
          - "9188:9188"
        volumes:
          - ./apisix/conf/dashboard.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.10

    rabbitmq01:
      image: rabbitmq
      container_name: rabbitmq01
      hostname: rabbitmq01
      environment:
        - TZ=Asia/Shanghai
        - RABBITMQ_DEFAULT_USER=root   #自定义登录账号
        - RABBITMQ_DEFAULT_PASS=123456 #自定义登录密码
        - RABBITMQ_ERLANG_COOKIE='secret_cookie'
      ports:
        - "15672:15672"
        - "5672:5672"
      volumes:
        - ./rabbitmq/mq1/data:/var/lib/rabbitmq
        - ./rabbitmq/mq1/conf:/etc/rabbitmq
      command:  bash -c "sleep 10; rabbitmq-server;"
      networks:
        caseor_bridge:
            ipv4_address: 172.0.10.11

    rabbitmq02:
      image: rabbitmq
      container_name: rabbitmq02
      hostname: rabbitmq02
      environment:
        - TZ=Asia/Shanghai
        - RABBITMQ_DEFAULT_USER=root   #自定义登录账号
        - RABBITMQ_DEFAULT_PASS=123456 #自定义登录密码
        - RABBITMQ_ERLANG_COOKIE='secret_cookie'
      ports:
        - "15673:15672"
        - "5673:5672"
      depends_on:
          - rabbitmq01
      volumes:
        - ./rabbitmq/mq2/data:/var/lib/rabbitmq
        - ./rabbitmq/mq2/conf:/etc/rabbitmq
      command:  bash -c "sleep 10; rabbitmq-server;"
      networks:
        caseor_bridge:
            ipv4_address: 172.0.10.12

    rabbitmq03:
      image: rabbitmq
      container_name: rabbitmq03
      hostname: rabbitmq03
      environment:
        - TZ=Asia/Shanghai
        - RABBITMQ_DEFAULT_USER=root   #自定义登录账号
        - RABBITMQ_DEFAULT_PASS=123456 #自定义登录密码
        - RABBITMQ_ERLANG_COOKIE='secret_cookie'
      ports:
        - "15674:15672"
        - "5674:5672"
      depends_on:
          - rabbitmq01
      volumes:
        - ./rabbitmq/mq3/data:/var/lib/rabbitmq
        - ./rabbitmq/mq3/conf:/etc/rabbitmq
      command:  bash -c "sleep 10; rabbitmq-server;"
      networks:
        caseor_bridge:
            ipv4_address: 172.0.10.13

# 开启web管理 
# rabbitmq-plugins enable rabbitmq_management 

# # 加入rabbitmq集群

# # rabbit1
# rabbitmqctl stop_app
# rabbitmqctl reset
# rabbitmqctl start_app

# # rabbit2
# rabbitmqctl stop_app
# rabbitmqctl reset
# rabbitmqctl join_cluster --ram rabbit@rabbit1
# rabbitmqctl start_app

# # rabbit3
# rabbitmqctl stop_app
# rabbitmqctl reset
# rabbitmqctl join_cluster --ram rabbit@rabbit1
# rabbitmqctl start_app

View Code

目前使用docker启动apisix,需要依赖etcd,

复制代码
    etcd:
        container_name: etcd
        hostname: etcd
        image: bitnami/etcd
        volumes:
          - ./etcd/data:/bitnami/etcd
        environment:
          ETCD_ENABLE_V2: "true"
          ALLOW_NONE_AUTHENTICATION: "yes"
          ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379" #https://github.com/apache/apisix-dashboard/issues/2756 需要更换为host域名不能使用0.0.0.0
          ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379"
        ports:
          - "2379:2379/tcp"
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.8

    apisix:
        container_name: apisix
        hostname: apisix
        image: apache/apisix        
        volumes:
          - ./apisix/log:/usr/local/apisix/logs
          - ./apisix/conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
        depends_on:
          - etcd
        ports:
          - "9088:9088/tcp"
          - "9180:9180/tcp"
          - "127.0.0.1:9090:9090/tcp"
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.9
    
    apisix-dashboard:
        container_name: apisix-dashboard
        image: apache/apisix-dashboard
        depends_on:
          - etcd
        ports:
          - "9188:9188"
        volumes:
          - ./apisix/conf/dashboard.yaml:/usr/local/apisix-dashboard/conf/conf.yaml
        networks:
          caseor_bridge:
                ipv4_address: 172.0.10.10

使用apisix dashboard的时候 会出现一个bug,需要在启动etcd的时候设置ETCD_ADVERTISE_CLIENT_URLS为host域名 而不能使用0.0.0.0

apisix的config yaml

复制代码
apisix:
    node_listen:
        - port: 9088
    enable_ipv6: true
    enable_control: true
    control:
        ip: "[::]"
        port: 9090
discovery:
  nacos:
    host:
      - "http://172.0.10.7:8848"
deployment:
    role: traditional
    role_traditional:
        config_provider: etcd
    admin:
        admin_listen:
            port: 9180
        allow_admin:
            - 0.0.0.0/0
        admin_key:
            - name: "admin"
              key: b848941cd4e1003f2f961a7786ecf75f
              role: admin
            - name: "viewer"
              key: dd3bc5bde63f272f554b91336bfcfcb3
              role: viewer
    etcd:
       host:
           - http://etcd:2379
       prefix: /apisix
       timeout: 30
#plugin_attr:
#    prometheus:
#        export_addr:
#            ip: "0.0.0.0"
#            port: 9091
#END

View Code

dashboard的config yaml

复制代码
conf:
  listen:
    host: 0.0.0.0     # `manager api` listening ip or host name
    port: 9188          # `manager api` listening port
  allow_list:           # If we don't set any IP list, then any IP access is allowed by default.
    - 0.0.0.0/0
  etcd:
    endpoints:          # supports defining multiple etcd host addresses for an etcd cluster
      - "http://etcd:2379"
                          # yamllint disable rule:comments-indentation
                          # etcd basic auth info
    # username: "root"    # ignore etcd username if not enable etcd auth
    # password: "123456"  # ignore etcd password if not enable etcd auth
    mtls:
      key_file: ""          # Path of your self-signed client side key
      cert_file: ""         # Path of your self-signed client side cert
      ca_file: ""           # Path of your self-signed ca cert, the CA is used to sign callers' certificates
    # prefix: /apisix     # apisix config's prefix in etcd, /apisix by default
  log:
    error_log:
      level: warn       # supports levels, lower to higher: debug, info, warn, error, panic, fatal
      file_path:
        logs/error.log  # supports relative path, absolute path, standard output
                        # such as: logs/error.log, /tmp/logs/error.log, /dev/stdout, /dev/stderr
    access_log:
      file_path:
        logs/access.log  # supports relative path, absolute path, standard output
                         # such as: logs/access.log, /tmp/logs/access.log, /dev/stdout, /dev/stderr
                         # log example: 2020-12-09T16:38:09.039+0800    INFO    filter/logging.go:46    /apisix/admin/routes/r1 {"status": 401, "host": "127.0.0.1:9000", "query": "asdfsafd=adf&a=a", "requestId": "3d50ecb8-758c-46d1-af5b-cd9d1c820156", "latency": 0, "remoteIP": "127.0.0.1", "method": "PUT", "errs": []}
authentication:
  secret:
    secret              # secret for jwt token generation.
                        # NOTE: Highly recommended to modify this value to protect `manager api`.
                        # if it's default value, when `manager api` start, it will generate a random string to replace it.
  expire_time: 3600     # jwt token expire time, in second
  users:                # yamllint enable rule:comments-indentation
    - username: admin   # username and password for login `manager api`
      password: admin
    - username: user
      password: user

plugins:                          # plugin list (sorted in alphabetical order)
  - api-breaker
  - authz-keycloak
  - basic-auth
  - batch-requests
  - consumer-restriction
  - cors
  # - dubbo-proxy
  - echo
  # - error-log-logger
  # - example-plugin
  - fault-injection
  - grpc-transcode
  - hmac-auth
  - http-logger
  - ip-restriction
  - jwt-auth
  - kafka-logger
  - key-auth
  - limit-conn
  - limit-count
  - limit-req
  # - log-rotate
  # - node-status
  - openid-connect
  - prometheus
  - proxy-cache
  - proxy-mirror
  - proxy-rewrite
  - redirect
  - referer-restriction
  - request-id
  - request-validation
  - response-rewrite
  - serverless-post-function
  - serverless-pre-function
  # - skywalking
  - sls-logger
  - syslog
  - tcp-logger
  - udp-logger
  - uri-blocker
  - wolf-rbac
  - zipkin
  - server-info
  - traffic-split

View Code

在文件夹下启动

复制代码
docker-compose -f microservice.yaml up

本地打开 http://localhost:9188 使用admin ,admin 登录

配置路由信息

这里使用的是nacos作为服务发现,具体查看nacos配置

启动以8083端口的服务

复制代码
dotnet run --urls=http://*:8083

打开浏览器调试下接口

接下来使用网关请求

再启动以8084端口的服务

nacos中出现了两个实例

继续使用网关请求

在log中的access.log 可以查看到网关请求到不同端口的服务

几个注意点:

1.etcd的ETCD_ADVERTISE_CLIENT_URLS 需要更换为host域名不能使用0.0.0.0

2.apisix的nacos配置在 config.yaml中的discovery

尽量使用host名称