【Spring Cloud系列学习】03.Spring Cloud各模块概述应用

Spring Cloud

0. 基础介绍

1. 简介

是一系列框架的有序集合,利用springboot的开发便利性(默认优于配置)简化了
分布式系统开发。

  1. 服务发现注册
  2. 配置中心
  3. 消息总线
  4. 负载均衡
  5. 熔断器
  6. 数据监控
  7. 等等

2. 与springboot的关系

  1. springboot 专注于快速高效的开发单个微服务
  2. springcloud 关注全局的服务治理
  3. springboot 可以离开springcloud单独开发
  4. springcloud 离不开springboot,属于依赖关系
  5. springboot 开发版本需和springcloud版本对应

3. 主要框架

  1. 服务发现:Eureka
  2. 服务调用:Feign
  3. 熔断器: Hystrix
  4. 服务网关: Zuul
  5. 分布式配置: Spring Cloud Config
  6. 消息总线: Spring Cloud Bus

dubbo相当于spring cloud的子集

3.1. Eureka 服务发现

  1. 类似于dubbo 和 zokeerper
  2. 包含两个组件:Eureka Server和Eureka Client
1. Eureka Server

提供服务注册服务,各个节点服务启动后,会在Eureka Server中注册,则server会在服务注册表中
存储所有可用服务节点的信息,这些信息会在管理界面中看到。

即一个微服务想让其他服务发现,就要让自己成为Eureka Client(客户端),即注册到服务端。

2. Eureka Client

是一个java客户端,用于简化和server的交互。

客户端应用启动后,会定时向服务端发送一个心跳(默认周期为30秒),若server端在多个心跳周期内没有发现某个
节点(客户端)的心跳,则服务端会从服务注册表中将该节点(客户端)移除(默认为90秒)。

3. Eureka Server开发
1. 在父工程中pom中添加版本锁定
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

需注意springboot版本和springcloud版本对应,否则会报错
参考版本对应

2. 新建模块作为服务发现的服务端
  1. pom 添加依赖
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
    
  2. 配置文件配置
    server:
      port: 8099
    eureka:
      client:
        register-with-eureka: false   #是否把当前模块注册到服务器中,本身就是服务器,所以为false
        fetch-registry: false     #是否从Eureka中获取注册信息
        service-url:    #Eureka客户端与服务端交互的地址
          defaultZone: http://localhost:${server.port}/eureka/
    
  3. 创建启动类

    添加注解@EnableEurekaServer

4. Eureka Client开发
  1. 在已开发模块中添加依赖
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    
  2. 修改配置文件
  3. 启动类

    添加注解@EnableEurekaClient

3.2. Feign 实现服务间的调用

前提是先能发现服务才可调用

1. 先搞清逻辑,A模块调用B模块,则操作A模块
  1. pom文件导入依赖

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    
  2. 创建要调用模块(B模块)的客户端接口

    @FeignClient("base-jpa")  //FeignClient用于指定从哪个服务调用功能
    public interface BaseJpaClient {
     //将需要的方法声明到该接口中
       @GetMapping("/label/{labelId}")
        public Result findById(@PathVariable("labelId") String labelId);
    }
    
  3. 启动类添加注解

    1. @EnableDiscoveryClient
    2. @EnableFeignClients //采用Feign的方式去发现
  4. 调用
    如:在controller中调用

    public class A{
        @Autowired
        private BaseJpaClient baseJpaClient;
        @GetMapping("/label/{labelId}")
        public Result findByLabelId(@PathVariable String labelId){
            return baseJpaClient.findById(labelId);
        }
     }
    
  5. 默认支持负载均衡

3.3. 熔断器(Hystrix)

雪崩效应

使得系统再出现依赖服务失效的时候,通过隔离系统所依赖的服务,防止服务级联失败,
同时提供失败回退机制,更好的应对失效

  1. feign本身就支持hystrix,所以无需再引入依赖
1.使用
  1. 针对调用的其他服务客户端(client),创建实现类
  2. 在客户端(client)上的注解@FeignClient中添加信息如下
    @FeignClient(value = "base-jpa", fallback = BaseJpaClientImpl.class)
    public interface BaseJpaClient{} 
    
  3. 在配置文件中添加
    feign:
      hystrix:
        enabled: true     #打开熔断器
    

当依赖的服务断掉后,调用该服务的方法会走指定的返回类(即fallback指定的类),当
依赖的服务重新连接上后,调用该服务则继续该有的执行,而不会走fallback。

3.4. 路由网关 Zuul

1. 提出问题
  1. 不同的微服务有不同的网络地址,外部的客户端可能需要调用多个服务的接口才能实现功能,
  2. 若客户端直接和微服务通信,则会出现如下问题
    1. 客户端会多次请求不同微服务,增加了客户端的复杂性
    2. 存在跨域请求,在一定场景下处理增加了复杂性
    3. 认证复杂,每一个服务都需要独立认证
2. 项目应用 路由转发
  1. pom文件导入依赖
    <dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    </dependency>
    </dependencies>
    
  2. 配置文件
    server:
      port: 8092
    spring:
      application:
        name: pro-web
    eureka:
      client:
        service-url:    #Eureka客户端与服务端交互的地址
          defaultZone: http://localhost:8099/eureka/
      instance:
        prefer-ip-address: true     #模块之间支持跨域
    zuul:
      routes:       #指定微服务及访问的路径跳转到的模块
        pro-base:         #指定微服务
          path: /base/**  #指定微服务的访问路径
          serviceId: pro-base   #上面指定的路径则跳转到该模块,即指定Eureka注册中心的服务id
    
  3. 创建启动类
    @SpringBootApplication
    @EnableEurekaClient
    @EnableZuulProxy
    public class WebApplication {}
    
3. 网关过滤器
参考pro_manager的ManagerFilter类

3.5.集中配置组件SpringCloud Config

  1. config server
  2. config client
    [外链图片转存失败(img-C83hO9xC-1568598984359)(/images/springcloud_config%20框架结构.png)]
1.config server

用于集中管理应用程序各个模块下的配置

  1. 将各模块的配置文件通过A-B的方式命名,然后统一到git或svn等平台管理,并将地址留用
    1. 文件命名规范:{application}-{profile}.yml或{application}-{profile}.properties
    2. application为应用名称,profile为开发环境,如开发,测试,生产等
  2. 在项目中创建配置中心微服务模块
    1. pom导入依赖
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-config-server</artifactId>
      </dependency>
      
    2. 配置文件
      server:
        port: 9080
      spring:
        application:
          name: pro-web
        cloud:
          config:
            server:
              git:
                uri: https://gitee.com/git账号/项目名.git   #配置文件存放git的访问路径
      
    3. 启动类
      @SpringBootApplication
      @EnableConfigServer
      public class ConfigApplication {}
      
    4. 测试访问获取

      访问http://localhost:9080/git中的文件名

2.config client
  1. 在某个模块中应用
    1. 将该模块的配置文件放在git中,模块中删除该文件
    2. 在pom文件中添加依赖
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-config</artifactId>
      </dependency>
      
    3. 添加一个配置文件bootstrap.yml,配置连接config服务的信息
      1. bootstrap的优先级高于application
      2. 一般情况下bootstrap.yml中配置的信息为系统级信息,application中配置的应用级信息
      spring:
        cloud:
          config:
            name: base    #git中该微服务的配置文件的名称前缀
            profile: dev  #git中该微服务的配置文件的名称后缀
            label: master   # git主干
            uri: http://localhost:9080 #指定配置服务的访问路径
      

3.6.消息总件 Bus

在微服务模块中添加一个监听,监听配置文件是否改变,若改变,重新获取配置文件,并编译项目
[外链图片转存失败(img-kEdx7aEV-1568598984361)(/images/springcloud_bus%20框架结构.png)]

1.简介
2. 应用
1. 服务端

在配置中心微服务模块中做如下操作

  1. pom文件添加依赖
    <dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-bus</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
    </dependency>
    </dependencies>
    
  2. 配置文件application.xml
    spring:
      rabbitmq:
        host: localhost   #bus需要消息队列
    management:   #暴露触发消息总线的地址
      endpoints:
        web:
          exposure:
            include: bus-refresh
    
2. 客户端
  1. pom引入依赖
    <dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-bus</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
    </dependency>
    <dependency><!-- 监听 -->
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency> 
    </dependencies>
    
  2. 配置文件(上传到git的文件)添加配置
    spring:
       rabbitmq:
          host: localhost   #bus需要消息队列
    
  3. 测试
    1. 启动Eureka、config(上面的服务端)及配置了bus的客户端
    2. 访问客户端的某个请求
    3. 修改git中该客户端的配置文件
    4. 以post的方式访问http://localhost:9080/actuator/bus-refresh,相当于发送一条消息到消息队列,注意该路径为配置中心服务模块的路径
    5. 此时监听器监听到消息队列有消息,会重新获取配置文件并编译项目
    6. 再次访问客户端的某个请求,会发现配置修改后
  4. 自定义配置

当某个模块中的配置文件中有自定义的配置文件,此时更新了配置文件中自定义属性的值后,再次访问值不会改变,
若想使其随着配置文件改变而改变,可以在controller上添加注解@RefreshScope

3.7.微服务容器部署和持续集成jenkins

所有操作需有前提,1已有Linux服务器,且安装了docker,若想本地操作,可安装xshell等远程操作工具

1.Dockerfile(手动发布镜像)
1. 简介
  1. 是由一系列命令和参数构成的脚本。能够把本地的代码发布到服务器成一个镜像的形式。
  2. 这些命令应用于基础镜像并最终创建一个新的镜像
2. 作用
  1. 对于开发人员:为开发团队提供完全一致的开发环境
  2. 对于测试人员:通过dockerfile文件可以直接创建一个新的镜像来工作
  3. 对于运维人员:在部署时,可以实现应用的无缝移植
3. 常用命令

image:镜像,tag:版本号

  1. FROM image_name:tag ->表示当前要制作的镜像依赖于tag版本的image_name(镜像名称)
  2. MAINTAINER user_name ->声明镜像的创建者
  3. ENV key value ->设置环境变量(键值对),可以有多条
  4. RUN command ->是Dockerfile的核心部分,执行指定命令,可以有多条
  5. ADD source_dir/file_dest_dir/file ->将宿主机(本地电脑)的文件复制到容器内,若是压缩文件,会复制后自动解压
  6. COPY source_dir/file_dest_dir/file ->将宿主机(本地电脑)的文件复制到容器内,若是压缩文件,会只复制不解压
  7. WORKDIR path_dir ->设置工作目录
  8. EXPOSE port1 port2 ->指定端口号,使容器内的应用可通过端口和外界交互
  9. CMD argument ->在构建容器时使用,会被docker run后的argument覆盖
  10. ENTRYPOINT argument ->在构建容器时使用,不会被docker run后的argument覆盖
4. 使用脚本创建镜像

以创建JDK 镜像为例

  1. 创建目录(在xshell中或直接在服务器上Linux下)
    mkdir -p /usr/local/docker_jdk8
    
    也可用xftp图形化界面直接创建文件
  2. 下载jdk8.tar.gz并上传到中的上面目录中
  3. 创建文件Dockerfile
    1. 该文件必须与第2步中的文件在同一目录下
    2. 该文件名称必须为Dockerfile
  4. 文件内容(示例)
    #依赖镜像名称和id(版本)
    FROM centos:7
    #声明创建者
    MAINTAINER bj
    #切换工作目录
    WORKDIR /usr
    #运行命令 创建目录
    RUN mkdir /usr/local/java
    #注意ADD后的文件是相对路径
    ADD jdk8.tag.gz /usr/local/java/
    #设置环境变量
    ENV JAVA_HOME /usr/local/java/jdk8
    ENV JRE_HOME $JAVA_HOME/jre
    ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tool.jar:$JRE_HOME/lib:$CLASSPATH
    ENV PATH $JAVA_HOME/bin:$PATH
    
  5. 切换目录到第一步创建的目录下
    cd /usr/local/docker_jdk8
  6. 执行如下命令构建镜像
    docker build -t = 'jdk1.8' .
    

    上面的命令表示构建一个叫jdk1.8的镜像在当前目录下,注意最后的空格和点表示当前目录

  7. 执行命令查看创建的镜像
    docker images
    
  8. 创建容器(先到根目录然后执行如下命令)
    docker run -id --name = myjdk8 jdk1.8
    
    1. –name 表示为容器指定名称
    2. jdk1.8 指定要创建容器的镜像是哪个,若有多个版本的镜像,可通过 镜像:版本号的方式来指定
  9. 查看已创建的容器
    docker ps
    
2. 私有仓库

是指对于一个应用可能在多处需要使用,每次使用都需要构建镜像,创建容器,通过私有仓库,
可以一次构建镜像将其放入私有仓库,需要使用的时候,直接下载镜像,创建容器即可,而无需再次构建。

1. 私有仓库搭建与配置
  1. 获取私有仓库的镜像

    docker pull registry
    
  2. 启动私有仓库容器

    docker run -di --name=registry -p 5000:5000 registry
    
    1. 打开浏览器 输入地址 http://ip地址:5000/v2/_catalog,此处的ip地址为服务器的ip地址
    2. 浏览器可看到{“repositories”:[]},表示私有仓库搭建成功并且内容为空。
  3. 修改 daemon.json

    vim /etc/docker/daemon.json
    

    添加内容{“insecure-registries”:[“ip地址:5000”]},用于让 docker信任私有仓库地址

    注意:
    看该文件是否修改镜像下载地址,默认国外地址下载较慢,可修改为如下国内地址(或其他)

    {"registry-mirrors":["https:docker.mirrors.ustc.edu.cn"]}
    

    该文件只有一个大括号,多个内容通过逗号分隔

  4. 重启docker

    systemctl daemon-reload
    systemctl restart docker
    
2.上传镜像到私有仓库
  1. 先启动私有仓库
    #查看已有容器
    docker ps -a
    #启动私有仓库的容器
    docker start 仓库容器名
    
  2. 查看已有镜像或者下载所需镜像
    #查看已有镜像
    docker images
    #下载所需镜像
    docker pull 镜像名
    
  3. 修改标记Tag,即标记此镜像为私有仓库中的镜像
    docker tag 镜像 服务端ip地址:5000/私有仓库中该镜像的名称
    

    此时通过docker images查看镜像会发现有两个该镜像,一个是原有的,一个是标记后的镜像

  4. 上传镜像到私有仓库
    docker push 服务端ip地址:5000/私有仓库中该镜像的名称
    
  5. 查看私有仓库
    通过浏览器查看 http://服务端ip地址:5000/v2/_catalog 可以看到刚上传的镜像
3. DockerMaven插件
1.微服务部署的方式
  1. 手动部署:先基于源码打包生成jar(或war)包,将包上传至虚拟机并拷贝到jdk容器
  2. 通过maven插件自动部署
2.Maven 自动部署的步骤
  1. 修改宿主机的Docker配置,让其可以远程访问
    vi /lib/systemd/system/docker.service
    

    其中ExecStart后面添加-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock

  2. 重启docker和私有仓库
  3. 在项目模块中操作
    1. pom文件导入插件
      <build>
          <!-- 当前工程的名称 -->
          <finalName>config</finalName>
          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
              </plugin>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>docker-maven-plugin</artifactId>
                  <configuration>
                      <!-- 镜像的名称标记 -->
                      <imageName>服务器ip地址:5000/${project.artifactId}/${project.version}</imageName>
                      <!-- 基础镜像 -->
                      <baseImage>jdk1.8</baseImage>
                      <!-- 进入后执行java -jar *.jar 打包命令 -->
                      <entryPoint>["java", "-jar", "/{project.build.finalName}.jar"]</entryPoint>
                      <resources>
                          <resource>
                              <targetPath>/</targetPath>
                              <directory>${project.build.directory}</directory>
                              <include>${project.build.finalName}</include>
                          </resource>
                      </resources>
                      <dockerHost>http://服务器ip:2375</dockerHost>
                  </configuration>
              </plugin>
          </plugins>
      </build>
      
    2. 确保该项目模块所需的依赖都已启动,如rabbitmq等
    3. 在idea打开Terminal视图,在project中选中模块,拖到Terminal视图

      注意默认idea没有加载Terminal,需通过file-》设置-》plugins-》选中Terminal,重启idea才可使用

    4. 执行命令mvn clean package docker:build -Dpushimage (依次为清理->打包->构建镜像->上传到私有仓库)
    5. 在服务器上通过命令查看镜像 docker images
    6. 启动容器 docker run -di --name=指定容器名 -p 端口号:指定端口号 镜像名:版本号
4.持续集成 jenkins

前提条件:代码托管到git或svn或码云等代码管理平台上

1.Gogs git图形化界面
  1. 下载gogs镜像 docker pull gogs/gogs

  2. 创建容器

    docker run -d --name=gogs -p 10022:22 -p 3000:3000 -v /var/gogsdata:/data gogs/gogs

    注意

    1. 第一个-p是内部使用,第二个-p是对外访问的,
    2. -v表示文件挂载, 表示把冒号后面的文件挂载到冒号前面指定的路径
  3. 在外部浏览器访问http://服务器ip地址:3000

    1. 选择数据库,可以选择Sqllite
    2. 修改域名和应用URL,指定服务器ip地址,
    3. 注册账号并登陆
    4. 创建仓库(即项目)
  4. 上传代码

    1. 在idea中的vcs菜单中选择启动版本控制合并,然后选择git
    2. 选中项目右键选择Git->Repository->Remotes
    3. 在URL中录入第三步创建仓库(项目)的地址,连接远程
    4. 选中项目右键选择Git->add 添加
    5. 选中项目右键选择Git->Commit Directory提交到本地
    6. 选中项目右键选择Git->Repository->Push提交到远程,此处需录入远程的用户名和密码
2.运用Jenkins实现持续集成
1. Jenkins
  1. Jenkins安装
    1. jdk安装 直接安装到宿主机上而不是创建容器
      1. jdk8-linux.rpm上传到服务器(可以是虚拟机)
      2. 执行安装命令 rpm -ivh jdk8-linux.rpm
        rpm方式安装的,其根目录为usr/java/jdk
    2. Jenkins的安装与启动
      1. 下载或直接上传,执行命令 wget https://pkg.jenkins.io/redhat/jenkins-…noarch.rpm
      2. 安装 rpm -ivh jenkins的rpm安装包
    3. 安装maven
      可以本地准备好上传或上传后在修改
      1. 修改conf目录下的setting中指定仓库地址
  2. 配置
    1. 通过vi /etc/sysconfig/jenkins打开配置文件
    2. 修改用户和端口
      JENKINS_USER="root"
      JENKINS_PORT=指定端口
      
  3. 启动服务 systemctl start jenkins
  4. 浏览器访问 http://服务器ip地址:指定的端口
    1. 此时需要登录密码,此密码在服务器/var/lib/jenkins/secrets/initialAdminPassword文件中
    2. 安装插件maven和git 是必须的,可能不成功
    3. 创建一个账户,登录进入
    4. 对于不成功的插件可通过系统管理-》管理插件中进行安装
    5. 系统管理-》全局工具配置,配置jdk,maven
2. 持续集成

浏览器访问http://服务器ip地址:指定的端口并登陆

  1. 创建任务

3.8.容器管理

1. 容器管理工具Rancher

1.简介

  1. 是开源的全栈化容器部署及管理工具

3.9.容器监控

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值