0%

方式一docker-zipkin+zipkin+sleuth

请求原理图

graph LR
请求-->微服务客户端-->sleuth采集请求-->zipkin发送请求的信息-->docker-zipkin接受并展示
sleuth 采样+++zipkin 发送分析展示采样数据
  1. 安装penzipkin/docker-zipkin 服务端,听说官方不建议编译,直接提供jar包了,因此采用docker方式进行部署

  2. 添加依赖在需要监控的服务

    1
    2
    compile('org.springframework.cloud:spring-cloud-starter-sleuth')
    compile('org.springframework.cloud:spring-cloud-starter-zipkin')
  3. 添加配置,在application.yml添加zipkin服务端地址,和采样比例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    spring:
    zipkin:
    base-url: http://10.14.0.7:14009/
    sleuth:
    web:
    client:
    enabled: true
    sampler:
    probability: 1.0 #采样比例0~1之间,1全部采样
  4. 访问http://10.14.0.7:14009/进行测试

测试结果
  1. 在eureka服务注册端添加没监控到请求
  2. 启动两个一样的服务提供者,端口不一致,以一个服务展示,但是能看到两个客户端
  3. 请求之后才能监控到

方式二docker-zipkin+rabbitMQ+sleuth(暂时未成功)

graph LR
请求-->微服务客户端-->sleuth采集请求-->mq发送请求的信息-->docker-zipkin接受并展示
  1. 修改docker-compose部署添加环境变量(目测该镜像还不支持改环境变量)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    version: '3'

    services:
    zipkin:
    restart: always
    image: openzipkin/zipkin
    environment:
    RABBIT_ADDRESSES: mq的地址
    RABBIT_PASSWORD: mq的密码
    RABBIT_USER: mq的用户名
    ports:
    - "14009:9411"
    deploy:
    replicas: 1
    restart_policy:
    condition: on-failure
    placement:
    constraints: [node.hostname == worker]
  2. 修改客户端依赖

    1
    2
    3
    compile('org.springframework.cloud:spring-cloud-starter-sleuth')
    //compile('org.springframework.cloud:spring-cloud-starter-zipkin') //注释这句
    compile('org.springframework.boot:spring-boot-starter-amqp')
  3. 修改配置文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #  zipkin:
    # base-url: http://10.14.0.7:14009/
    sleuth:
    web:
    client:
    enabled: true
    sampler:
    probability: 1.0 #采样比例0~1之间,1全部采样
    rabbitmq:
    port: 14002
    host: 10.14.0.1
    username: root
    password: adminroot
  4. 测试失败,读不到服务,通过看docker-zipkin似乎是这里的mq没启动起

数据持久化zipkin+mysql

待更新。。。

参考:Baeldung-SpingCould-Sleuth

史上最简单的 SpringCloud 教程 | 终章

Spring Cloud(十二):分布式链路跟踪 Sleuth 与 Zipkin【Finchley 版】

SpringCould Bus是将分布式的节点用轻量的消息代理连接起来。用于服务间广播、通信、监控等。

该篇实现:通过bus实现配置修改后通知服务更改

步骤

  1. 在configclient的基础上添加依赖

    1
    compile('org.springframework.cloud:spring-cloud-starter-bus-amqp')
  2. Hicontroller类添加注解@RefreshScope

  3. 在配置文件添加mq的服务器地址,和开启刷新

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    spring:  
    rabbitmq:
    host: 112.74.51.136
    port: 14002
    username: root
    password: adminroot
    management:
    endpoints:
    web:
    exposure:
    include: ["health","info","bus-refresh"]
  4. 测试,依次运行注册中心、配置中心、该服务,然后访问接口,然后修改git config下的配置信息,然后访问接口,还是没变,需要调用127.0.0.1:8097/actuator/bus-refresh?destination=config-client:8097其中的config-client:8097是指定更新那台服务,也可以不指定参数,默认就是更新所有,然后在访问测试接口,发现已经配置已经改变了。

架构优化

可以在config-server添加config-client的配置,这样就可以调配置刷新127.0.0.1:8096/actuator/bus-refresh/接口,刷新所有配置客户端的配置了,注意依赖要加上 compile('org.springframework.cloud:spring-cloud-starter-config')config-client的配置依赖,因为config-client的依赖和config-serverbus-refresh接口不一样

image-20200811155609870

Docker之基础系统Alpine Linux

Alpine是一个linux迷你系统,体积小、安全,docker中ubuntu的替代系统

  • 小巧: 官方镜像docker pull alpine只有4.15M
  • 安全: 面向安全的轻量发行版
  • 简单: 提供apk包管理工具从仓库管理安装
  • 容器的基础镜像

gliderlabs/docker-alpine

文档Alpine

基本使用

Alpine仓库搜索你要安装的组件(package)然后执行apk add --no-cache <Package name>

docker 中alpine使用

1
2
3
4
5
6
7
8
9
10
11
docker run alpine echo '123' #输出123,运行完镜像即摧毁
docker run -it --name myalpine alpine #运行一个容器并进入
### alpine常用命令,apk --help
apk info #查看安装的apk
apk update #更新镜像列表
cat /etc/apk/repositories #查看源
#http://dl-cdn.alpinelinux.org/alpine/v3.7/main
#http://dl-cdn.alpinelinux.org/alpine/v3.7/community
echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories #添加测试源,记得apk update
cat /etc/apk/arch #查看系统版本Architecture,修改之后,之后的安装包都以该修改后的为准
apk upgrade #升级系统软件,解决编译版本过低等问题

利用docker 构建mysql镜像

1
2
3
FROM alpine:3.5
RUN apk add --no-cache mysql-client
ENTRYPOINT ["mysql"]

构建opencv镜像

1
2
3
FROM alpine:3.5
RUN apk add --no-cache opencv
ENTRYPOINT ["opencv"]

参考

Alpine Linux 使用简介

1
2
3
4
5
6
7
8
9
10
#采用国内阿里云的源,文件内容为:
cat > /etc/apk/repositories <<EOF
https://mirrors.aliyun.com/alpine/v3.7/main/
https://mirrors.aliyun.com/alpine/v3.7/community/
https://mirrors.aliyun.com/alpine/edge/testing/
EOF
# 如果采用中国科技大学的源,文件内容为:
https://mirrors.ustc.edu.cn/alpine/v3.6/main/
https://mirrors.ustc.edu.cn/alpine/v3.6/community/
https://mirrors.ustc.edu.cn/alpine/edge/testing/

mac开发环境

  1. 环境准备

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 安装开发基本组件(一般都安装了)可以跳过
    xcode-select --install
    # 安装ant,这里是使用Homebrew进行安装,为了方便管理
    brew install ant
    # 编辑配置文件(其实就vim编辑配置文件)
    brew edit opencv
    >修改为 -DBUILD_opencv_java=ON
    # 最后安装opencv,依赖于python2,可以提前建好,也可以通过依赖的方式自动安装
    brew install --build-from-source opencv
  2. 安装成功后jar包位于/usr/local/Cellar/opencv/3.x.x/share/OpenCV/java/

  3. idea设置vm启动参数-Djava.library.path=/usr/local/Cellar/opencv/3.4.3/share/OpenCV/java/

问题
  1. Permission denied @ dir_s_mkdir

    解决:重建目录

    1
    2
    3
    4
    sudo mkdir /usr/local/Frameworks
    sudo chown $(whoami):admin /usr/local/Frameworks
    # 测试
    brew link python

idea+springboot+opencv3.4.1+alpine

安装

由于alpine apk add opencv 运行报错,等待opencv出正式版

等待升级中。。。。。。。

opencv_java341.dll

Docker 安装 Oracle

镜像:sath89/oracle-12c

挂载需要修改权限

chown -R 1001:1001 /data/oracle

docker run -d –name oracle -p 8080:8080 -p 1521:1521 -e TZ=Asia/Shanghai sath89/oracle-12c

类别 host container 备注
port 1521 1521
port 8080 8080
volume /dockerdata/manager/oracledata/initdb /docker-entrypoint-initdb.d 初始化导入数据库用(非必需)
volume /dockerdata/manager/oracledata/data /u01/app/oracle
env IMPORT_FROM_VOLUME true 触发首次运行自动初始化数据(非必需)

oracle初始用户

1
2
3
4
5
6
7
8
port: 1521
sid: xe
service name: xe
username: system
password: oracle
user: sys
password: oracle
connect as sysdba: true

运行完成后,注意这里第一次运行要初始化,注意看日志,等待它完成

到处dmp文件:exp manager/manager buffer=64000 file=/test.dmp full=y

配置

修改数据库服务名xepdborcl

参考:Oracle 更改服务名方法

  1. 进入容器内执行命令,连接Oracle,执行sqlplus sys/oracle as sysdba 进入oracle,其中sys为用户名,oracle为密码,sysdba作为系统dba登入

    1
    2
    show parameter service_name #显示服务名
    alter system set service_names='pdborcl' scope=both; #更改服务名为pdborcl
  2. 添加表空间MANAGERDATASPACE

    1
    2
    3
    4
    5
    6
    7
    CREATE TABLESPACE MANAGERDATASPACE
    LOGGING
    DATAFILE '/u01/app/oracle/oradata/xe/MANAGERDATASPACE.DBF'
    SIZE 32M
    AUTOEXTEND ON
    NEXT 32M MAXSIZE UNLIMITED
    EXTENT MANAGEMENT LOCAL;
  3. 服务端更改完成,客户端的连接也要更改listener.ora文件,这里不记录

新建用户并导入dmp文件初始数据库

  1. 通过plsql添加用户manage

    user右键new 新建用户,设置 default tablespace=users,temp tablespace=temp

    role选项卡添加connect、dba、resource

  2. ftp上传文件dmp备份文件到挂在目录/dockerdata/manager/oracleinitdb/initdb

  3. 进入容器执行切换到/docker-entrypoint-initdb.d目录imp manager/manager file=manager20180413am1052.dmp log=imp_sysdb.log grants=no full=y导入恢复数据

数据库前的准备工作/创建数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
--创建表空间
create tablespace SY_DB logging datafile '/u01/app/oracle/oradata/SY_DB.DBF' size 50m autoextend on next 50m maxsize 20480m extent management local;
--创建用户
create user SY_DB identified by "SY_DB@2018" default tablespace SY_DB temporary tablespace TEMP profile DEFAULT password expire;
-- Grant/Revoke role privileges
grant dba to SY_DB;
--给用户分配权限
grant create any table to SY_DB;
grant create any view to SY_DB;
grant create user to SY_DB;
grant drop tablespace to SY_DB;
grant unlimited tablespace to SY_DB;
--查询用户密码有效期
select * from dba_profiles where profile='DEFAULT' and resource_name='PASSWORD_LIFE_TIME';
--查询用户和密码
select username,password from dba_users;
--修改用户密码(密码里面最好不要有@符号,不然执行导入命令时一直无权限)
alter user SY_DB identified by mimaoracle;
--去除用户密码有效期
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;
--创建虚拟目录存储导出文件
create directory db_bak as '/docker-entrypoint-initdb.d';

数据库导入导出(容器bash执行)

1
2
3
4
--数据泵导入文件
impdp SY_DB/mimaoracle DIRECTORY=db_bak DUMPFILE=SY_DB20190829.DMP SCHEMAS=SY_DB
--数据泵导出文件
expdp SY_DB/"""SY_DB@2018"""@orcl DIRECTORY=db_bak DUMPFILE=SY_DB20190829.DMP SCHEMAS=SY_DB;

修改字符集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- 进入sql命令行
sqlplus sys/oracle as sysdba
--若此时数据库服务器已启动,则先执行 SHUTDOWN IMMEDIATE 命令关闭数据库服务器,
然后执行以下命令:
SQL>shutdown immediate
SQL>STARTUP MOUNT
SQL>ALTER SYSTEM ENABLE RESTRICTED SESSION;
SQL>ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
SQL>ALTER SYSTEM SET AQ_TM_PROCESSES=0;
SQL>ALTER DATABASE OPEN;
SQL>ALTER DATABASE CHARACTER SET ZHS16GBK;
SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE ZHS16GBK;
--执行错误,未解决该错误
--ERROR at line 1:
--ORA-12712: new character set must be a superset of old character set
SQL>SHUTDOWN IMMEDIATE
SQL>STARTUP

问题

  1. 导入表空间报错

    解决将manager20180413am1052.dmp文件内容中的 MANAGERDATASPACE替换USERS

    待优化处理:???

hyper-v设置静态ip

创建NAT网络

用管理员权限运行powershell,下面命令会创建一个NAT内部网络,网段为192.168.204.0/24,可以在网络适配器可以找到新建的NAT-Docker网络适配器

1
2
3
4
5
6
7
8
#创建新的虚拟交换机NAT-Docker
New-VMSwitch –SwitchName "NAT-Docker" –SwitchType Internal –Verbose
#查看所有网路适配器,找到对应ifIndex 值
Get-NetAdapter
#新建一个NAT网关192.168.204.181,注意替换InterfaceIndex为ifIndex值
New-NetIPAddress –IPAddress 192.168.204.1 -PrefixLength 24 -InterfaceIndex 37 –Verbose
#创建一个nat网络
New-NetNat –Name NATNetwork –InternalIPInterfaceAddressPrefix 192.168.204.0/24 –Verbose

配置NAT网络

在新建的网络适配器NAT-Docker设置固定ip为192.168.204.1,dns记得也要设置202.96.128.86根据自己实际情况设置dns

在hyper-v虚拟机里切换centos使用该网络

centos配置静态ip

在centos修改网络配置文件vim /etc/sysconfig/network-scripts/ifcfg-eth0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
#BOOTPROTO="dhcp"
BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="eth0"
UUID="d49f62d7-9c2a-4f6f-8077-605d0dd65eea"
DEVICE="eth0"
ONBOOT="yes"
#---以下新加
NM_CONTROLLED="no"
IPADDR="192.168.204.181"
NETMASK="255.255.255.0"
GATEWAY="192.168.204.1"
BROADCAST="192.168.204.255"
DNS1="8.8.8.8"

执行service network restart重启网络

端口映射(需管理员权限)

1531476067353

1
2
3
4
5
6
7
8
9
10
#查询端口映射情况
netsh interface portproxy show v4tov4
#添加端口映射
netsh interface portproxy add v4tov4 listenport=外网端口 listenaddress=主IP connectaddress=私网IP connectport=私网IP端口
#eg
netsh interface portproxy add v4tov4 listenport=14014 listenaddress=192.168.1.158 connectaddress=192.168.204.182 connectport=14014
#删除一个端口映射
netsh interface portproxy delete v4tov4 listenaddress=主IP listenport=外网端口
#eg
netsh interface portproxy delete v4tov4 listenaddress=192.168.1.158 listenport=14014

1531475386029

参考Hyper-V 共享式网络链接 端口映射

双网卡

设置/etc/sysconfig/network,决定走那个网关和网卡

1
2
GATEWAY=10.2.2.1
GATEWAYDEV=em3

在网卡配置文件里面只有一个网卡设置网关,内网的不要设置

问题

  1. 端口偶发性映射失效,重启失效

    解决:目前删除重新添加,也可以添加个脚本,待寻找更好的方法

    参考:

    netsh interface portproxy 偶发性失效

    netsh portproxy not working after reboot

  2. 网络配置实现,使用ip a s查看可以一个网卡下有两个ip

    原因:存在相同名字的网卡配置文件,但后缀不一样,主要是由于备份原来文件导致的,例如.back等,

    解决:千万不要在当前目录进行备份,且不要用后缀模式

  3. 设置静态网络时,出现双ip问题

    原因:未知

    解决:在网络配置文件添加NM_CONTROLLED=no然后重启

  4. 网段如何计算,网段计算原理,ip后面的16和24是什么意思,在线计算子网掩码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #------概念-------
    192.168.0.0(ip)/16(掩码位)
    掩码:255.255.0.0 二进制:11111111.11111111.00000000.00000000总共就16位
    第一个(192.168.0.0网络)和最后一个(192.168.255.255广播)是固定网络地址也被称为CIRD
    #------------举例16位--------
    192.168.0.0/16
    转换为8位二进制就是
    二进 11000000.10101000.00000000.00000000
    掩码 11111111.11111111.00000000.00000000
    16就代表前面16位不动,所有就有192.168.0-256.0-256共65536个可用ip
    减去192.168.0.0和192.168.255.255,剩下可用ip位65534个
    #------------举例24位--------
    192.168.0.0/24
    转换为8位二进制就是
    二进 11000000.10101000.00000000.00000000
    掩码 11111111.11111111.11111111.00000000
    16就代表前面16位不动,所有就有192.168.0.0-256共256个可用ip
    减去192.168.0.0和192.168.0.255,剩下可用ip位254个

配置(config)中心

作用多服务统一配置管理,主要分配置中心服务端,和配置中心客户端(主要存储配置)

image-20200811155609870

Config Server

  1. 新建一个springboot项目,取名configserver,勾选

    • Could discovery-> eureka server 注释掉了,引用了不注册报错,如果要用,就注册就行,这里是测试config所以先不注册
    • Could config->config server
  2. application启动类添加@EnableConfigServer

  3. 新建一个git配置文件仓库,这里就在当前工程创建,因为这个反正都要上传git,在项目目录新建一个config目录,然后在目录里新建一个配置仓库testrepo,再在仓库添加配置文件config-client-dev.properties内容如下

    1
    2
    config-client.testsmsg = hello config me
    test = haa
  4. 然后git commit push推送到远程分支

  5. 在配置文件application.yml添加如下内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    server:
    port: 8096
    spring:
    application:
    name: config-server
    cloud:
    config:
    label: master #配置仓库分支
    server:
    git:
    uri: https://github.com/xuanfong1/SpringCould/ #配置仓库git地址
    search-paths: config/testrepo #配置仓库路径
    username: #访问git仓库的用户名,这里因为是开放项目所以不需要设置
    password: #访问git仓库的密码
  6. 访问http://127.0.0.1:8096/config-client/dev/master这个地址读取配置文件

    下面介绍http请求地址与资源文件映射问题

    Url : /{application}/{profile}[/{label}]

    资源文件格式可以为

    • /{application}-{profile}.yml

    • /{label}/{application}-{profile}.yml

    • /{application}-{profile}.properties

    • /{label}/{application}-{profile}.properties

      举例:master分支有配置文件config-client-dev.properties访问的url为ip:port/config-client/dev/master

config client

  1. 新建一个springboot项目,取名configserver,勾选

    • web->web
    • Could config->config client
  2. 修改配置文件application.properties一定要修改为**bootstrap.yml**并添加如下内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    server:
    port: 8097
    spring:
    application:
    name: config-client
    cloud:
    config:
    label: master #指明远程仓库的分支
    profile: dev #dev(开放)、test(测试)、pro(正式)
    uri: http://127.0.0.1:8096/ #配置中心地址
  3. 添加一个api接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @RestController
    public class HiController {
    @Value("${test}") //调用配置中心的配置
    String test;

    @RequestMapping(value = "/hi")
    public String hi(){
    return test;
    }
    }
  4. 访问http://127.0.0.1:8097/hi进行测试

配置中心高可用

config server
  1. 添加依赖compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-server')

  2. Application启动类添加注解@EnableEurekaClient

  3. Application.yml配置文件增加

    1
    2
    3
    4
    eureka:
    client:
    service-url:
    defaultZone: http://127.0.0.1:8091/eureka/ #注意要加eureka,不然找不到
config client
  1. 添加依赖compile('org.springframework.cloud:spring-cloud-starter-netflix-eureka-server')

  2. Application启动类添加注解@EnableEurekaClient

  3. bootstrap.yml配置文件修改如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    server:
    port: 8097
    spring:
    application:
    name: config-client
    cloud:
    config:
    label: master #指明远程仓库的分支
    profile: dev #dev(开放)、test(测试)、pro(正式)
    # uri: http://127.0.0.1:8096/ #配置中心地址 ,用eureka就不是ip地址了
    discovery:
    enabled: true
    service-id: config-server #这里用服务名

    eureka:
    client:
    service-url:
    defaultZone: http://127.0.0.1:8091/eureka/ #注意要加eureka,不然找不到

    所以多个config-server运行,通过负载均衡就可以达到高可用

    测试

    依次运行服务注册中心、配置中心服务、读配置中心的客户端服务

    访问http://127.0.0.1:8097/hi进行测试

    图示

       graph LR
    A[git仓库] -->B(config server)
    A[git仓库] -->B1(config server)
    A[git仓库] -->B2(config server)
    B --> C{负载均衡}
    B1 --> C{负载均衡}
    B2 --> C{负载均衡}
    C --> D[service A]
    C --> E[service B]
    F[eureka service]

使用本地文件作为配置中心

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server:
port: 8096
spring:
application:
name: config-server
profiles:
active: native #这里进行仓库预选,可设置native和git,分别对应spring.cloud.config.server下面的值
cloud:
config:
label: master #配置仓库分支
server:
git:
uri: https://github.com/xuanfong1/SpringCould/ #配置仓库git地址
search-paths: config/testrepo #配置仓库路径
# username: #访问git仓库的用户名,这里因为是开放项目所以不需要设置
# password: #访问git仓库的密码
native: #本地配置文件仓库的绝对路径
search-locations: /Users/xuanleung/workspace/SpringCould/config/testrepo
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:8091/eureka/ #注意要加eureka,不然找不到

公共配置文件

1
2
3
4
5
6
application.properties #公共配置文件,所有服务都会加载这个默认配置文件,适合放公共的数据库配置等
application-dev.properties #公共带环境的配置文件,dev环境会默认加载这个公共配置文件
config-client-dev.properties #config-client服务的私有配置
test-dev.properties #部分项目的公共配置,如一些项目引用mysql,一些不引用
#使用指定配置,需要在项目中设置下面这个选项
spring.cloud.config.name = config-client,test #指定配置文件,如果不需要指定,注释该行

额外

如果要使用vm启动参数,需要在config client设置如下三个参数

1
2
3
4
#使用vm启动参数,去掉下面的注释
spring.cloud.config.allowOverride=true
spring.cloud.config.overrideNone=false
spring.cloud.config.overrideSystemProperties=false

疑问:vm设置-Dserver.port等参数时,又不需要上面的设置
解释:vm参数如果不设置上面的会被配置文件里面的覆盖,如果配置文件里面没有设置,那就是用的vm的了

加载顺序

举例server.port

  1. client 里面的resources/bootstrap.yml

  2. vm里面-Dserver.port

  3. config里面config-client-dev.properties

三个都设置,使用3,只设置1,2使用2,只设置1,使用1

可推测优先级3>2>1

开发加载自己配置优化

利用默认分支功能,全局修改所有微服务为自己的配置

  1. 新建个自己的配置分支
  2. 复写spring config server启动参数spring.cloud.config.server.git.default-label=my-baranch为自己的分支号
  3. 注意不要在spring config client指定分支spring.cloud.config.label=master

SpringCould 路由网关(Zuul)

Zuul的主要功能是路由转发和过滤器。例如/api/user转发到到user服务,/api/shop转发到到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能。

zuul功能点(下面只简单介绍勾选的)
  • Authentication 认证
  • Insights 洞察?
  • Stress Testing 压力测试
  • Canary Testing 金丝雀测试
  • Dynamic Routing 动态路由
  • Service Migration 服务迁移
  • Load Shedding 加载脱落
  • Security 安全
  • Static Response handling 静态响应处理
  • Active/Active traffic management 活动/活动流量管理

步骤

  1. 新建springboot项目勾选如下

    • web->web
    • Could discovery-> eureka server
    • Could routing->zuul
  2. EurekazuulApplication启动类添加注解@EnableZuulProxy开启zuul功能@EnableEurekaClient也需要注册到服务中心

  3. application.yml添加如下配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    server:
    port: 8095
    spring:
    application:
    name: zuul-client
    eureka:
    client:
    service-url:
    defaultZone: http://127.0.0.1:8091/eureka/ #注意要加eureka,不然找不到
    zuul:
    routes:
    api-a:
    path: /api-a/** #以/api-a/ 开头的请求都转发给ribbon-client服务
    serviceId: ribbon-client
    api-b:
    path: /api-b/** #以/api-b/ 开头的请求都转发给feign-client服务
    serviceId: feign-client
  4. 依次启动注册中心、ribbon服务端、feign服务端、zuul服务端

    http://127.0.0.1:8095/api-b/sayhi?name=32访问的就是feign服务端

    注意:api-b不需要在control里面添加路径,只需要添加sayhi就行

    http://127.0.0.1:8095/api-a/resthi?name=32访问的就是ribbon服务端

  5. 到此就实现了路由功能

服务过滤

服务过滤安全校验功能等,新建一个MyFilter类注意加注解@Component,然后继承ZuulFilter

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
@Component
public class MyFilter extends ZuulFilter {

@Override
public String filterType() {
return "pre"; //pre:路由之前,routing:路由之时,post:路由之后,error:发送错误调用
}

@Override
public int filterOrder() {
return 0; //filterOrder:过滤的顺序
}

@Override
public boolean shouldFilter() {
return true; //shouldFilter:这里可以写逻辑判断,是否要过滤,本文true,永远过滤。
}

@Override
public Object run() throws ZuulException {
//run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。
RequestContext ctx=RequestContext.getCurrentContext();
HttpServletRequest request=ctx.getRequest();
System.out.print("method:"+request.getMethod()+",url:"+request.getRequestURL().toString());
Object token=request.getParameter("token");
if (token==null){
System.out.print("token is null");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
try {
ctx.getResponse().getWriter().write("token is null");
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
System.out.print("ok");
return null;
}
}

在ribbon+restTemplate方式使用熔断器hystrix

阻止服务故障的“雪崩”效应(我简称保险)

  1. ribbonrest项目上添加compile('org.springframework.cloud:spring-cloud-starter-netflix-hystrix')该依赖(这里用的gradle,maven做相应格式修改),或者直接新建一个项目勾选如下

    • web->web
    • Could discovery-> eureka server
    • Could routing->ribbon
    • Could Circuit Breaker->Hystrix
  2. application启动类添加一个注解@EnableHystrix拉上保险开关

  3. 修改服务调用类HelloService

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    @Service
    public class HelloService {
    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "hiError") //调用发生错误就调用hiError方法
    public String hiService(String name){
    //eureka-client为服务提供者的spring.application.name=eureka-client
    return restTemplate.getForObject("http://eureka-client/hi?name="+name,String.class);
    }
    //发生错误调用的方法
    public String hiError(String name) {
    return "hi,"+name+",sorry,error!";
    }
    }
  4. 启动该服务(8093),然后访问http://127.0.0.1:8093/resthi?name=32,然后再停止两台服务提供者的其中一台,然后刷新一台提示错误,一台正常访问

    启动顺序 访问结果 再启动 结果
    注册中心-服务提供者(1和2)-服务消费者 2台交替访问
    注册中心-服务提供者(1)-服务消费者-服务提供者(2) 1能访问
    注册中心-服务提供者(1和2)-服务消费者-停止1 1抛异常,2正常访问 再启动1 恢复时间慢
    注册中心-服务提供者(1和2)-服务消费者(开启了熔断器)-停止1 1返回熔断器自定义的错误信息,2正常访问 再启动1 马上可以交替访问

在feign模式使用熔断器

Feign是自带断路器的

  1. 新建SchedualServiceHiHystric实现服务调用的接口

    1
    2
    3
    4
    5
    6
    7
    @Component
    public class SchedualServiceHiHystric implements FeignSchedualService{
    @Override
    public String sayHiFromEurekaClient(String name) {
    return "sorry "+name;
    }
    }
  2. 在服务调用接口的@FeignClient添加fallback指向刚刚实现这个接口的类

    1
    2
    3
    4
    5
    @FeignClient(value = "eureka-client",fallback = SchedualServiceHiHystric.class) //指定调用那个服务(服务名spring.application.name)
    public interface FeignSchedualService {
    @RequestMapping(value = "/hi",method = RequestMethod.GET) //指定调用eureka-client服务的那个接口
    String sayHiFromEurekaClient(@RequestParam(value = "name") String name);
    }
  3. application配置文件添加该配置启用熔断器

    1
    2
    3
    feign:
    hystrix:
    enabled: true
  4. 依次启动注册中心,该服务(8094),然后访问http://127.0.0.1:8094/sayhi?name=32,启动测试见上面的第四步骤

    区别:服务提供者挂了一个不会交替返回正确错误信息,只要还有一个服务正常就返回正确信息,直到所有服务提供者挂了才返回错误信息。

参考

用 Feign Hystrix 进行服务集成

forezp/SpringCloudLearning

服务调用方式

  • 第一种方式:ribbon+restTemplate
  • 第二种方式:feign(默认集成ribbon)

Feign 采用的是基于接口的注解,默认整合了ribbon(负载均衡)。

建立服务提供者

建立服务消费者

  1. 新建springboot项目勾选如下

    • web->web
    • Could discovery-> eureka server
    • Could routing->feign
  2. application.yml添加如下配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    server:
    port: 8094
    spring:
    application:
    name: feign-client
    eureka:
    client:
    service-url:
    defaultZone: http://127.0.0.1:8091/eureka/ #注意要加eureka,不然找不到
  3. EurekafeignApplication.java类添加注解@EnableFeignClients标记为Feign服务

  4. 新建一个服务调用接口类FeignSchedualService.java

    1
    2
    3
    4
    5
    @FeignClient(value = "eureka-client") //指定调用那个服务(服务名spring.application.name)
    public interface FeignSchedualService {
    @RequestMapping(value = "/hi",method = RequestMethod.GET) //指定调用eureka-client服务的那个接口
    String sayHiFromEurekaClient(@RequestParam(value = "name") String name);
    }
  5. 新建一个对外访问HiController.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @RestController
    public class HiController {
    @Autowired
    FeignSchedualService feignSchedualService;

    @RequestMapping(value = "/sayhi",method = RequestMethod.GET)
    public String sayHi(@RequestParam String name){
    return feignSchedualService.sayHiFromEurekaClient(name);
    }
    }
  6. 依次启动eureka注册中心、eureka服务提供者(2个以上)、feign服务消费者

  7. 访问http://127.0.0.1:8094/sayhi?name=32就可以看到返回不同的端口了