SpringCloud学习笔记

SpringCloud

在这里插入图片描述
解决方案: Spring Cloud 生态: SpringBoot

1.Spring Cloud NetFlix 一站式解决方案
api网关 ,zuul组件
Feign —HttpClinet—Http通信方式,同步,阻塞
服务器足额从发现 Eureka
熔断机制:Hystrix

2.Apache Dubbo Zookeeper 半自动 ,需要整合别人
API :没有,找第三方,或者自己实现
Dubbo:
Zookeeper
借助 Hystrix
Dubbo 不完善

3.Spring Cloud Alibaba 一站式解决方案 简单

解决关键
1.api
2.HTTP,RPC
3.注册和发现
4.熔断机制

在这里插入图片描述

请添加图片描在这里插入图片描述述

SpringCloud入门

1.新建maven项目

2.导包

 <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <lombok.version>1.16.10</lombok.version>
    </properties>

  <dependencyManagement>
        <dependencies>

            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.SR1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.1.4.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>


            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.1.10</version>
            </dependency>

     <!-- 启动器-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>1.3.2</version>
            </dependency>
<!--            log4j-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>
      <!--      lombok-->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

3.新建一个api的 model 模块

导入相应的依赖,有的是 父类里面有 就可以不用导入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.it</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springclound-api</artifactId>

  <!--  写需要的依赖,父依赖有就不用写-->

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

api 的 model --写实体类的(pojo)

package com.it.pojo;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;


@Data
@NoArgsConstructor
@Accessors(chain = true)
public class Dept implements Serializable {  //Dept 实体类

    private Long id; //主键
    private  String name;
    //一个服务对应一个数据库,同一个信息可能存在不同数据库
    private  String db_source;

    public Dept(String name) {
        this.name = name;
    }
}

4.新建一个实现功能的model
请添加图片描述
1.导入相应的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.it</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-dept-8001</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>


    <dependencies>
        <!--完善监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--开启eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <!--拿到实体类-->
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>springclound-api</artifactId>
           <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--   jetty-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <!--热部署工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>springclound-api</artifactId>
            <version>1.0-SNAPSHOT</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

</project>

2.配置相应的yml

server:
  port: 8001


#mybatis配置
mybatis:
  type-aliases-package: com.it.pojo
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml


#spring配置
spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
    username: root
    password: root

#Eureka配置

#Eureka配置
eureka:
  client:
    service-url:  #监控页面
      defaultZone: http://localhost:7001/eureka/  #发布位置, 可以设置集群 ,所有直接把所有集群 都加上去
  instance:
    instance-id: springcloud-dept-8001  #修改eureka 上的默认描述信息

#info配置
info:
  app.name: song's first springcloud program
  company.name: song666

3.然后写对应的service 和dao ,controller层 以及相应的mybatis配置等

DeptController类

package com.it.controller;


import com.it.pojo.Dept;
import com.it.service.DeptService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//提供restful服务
@RestController
public class DeptController {


    @Autowired
    private DeptService deptService;

    @Autowired
    private DiscoveryClient client;

    @PostMapping("/dept/add")
    public boolean addDept(Dept dept)
    {
        return deptService.addDept(dept);
    }

    @GetMapping("/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id)
    {
        return deptService.queryById(id);
    }


    @GetMapping("/dept/list")
    public List<Dept> queryAll()
    {
        return deptService.queryAll();
    }


    //注册进来的微服务,获取一些信息
    @GetMapping("/dept/discovery")
    public  Object discovery()
    {
        //获取微服务列表清单
        List<String> services=client.getServices();
        System.out.println("discovery=>services: "+services);

        //得到微服务的具体信息
        List<ServiceInstance> instances = client.getInstances("SPRINGCLOUD-PROVIDER-DEPT");
        for (ServiceInstance instance : instances) {
            System.out.println(
                      instance.getHost()+"\t"+
                      instance.getPort()+"\t"+
                      instance.getUri()+"\t"+
                      instance.getServiceId()
            );
        }
                return this.client;
    }


}

Deptdao接口

package com.it.dao;


import com.it.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

import java.util.List;

@Mapper
@Repository
public interface DeptDao {

    public boolean addDept(Dept dept);

    public Dept queryById(Long id);

    public List<Dept> queryAll();



}

DeptService接口

package com.it.service;

import com.it.pojo.Dept;

import java.util.List;

public interface DeptService {


    public boolean addDept(Dept dept);

    public Dept queryById(Long id);

    public List<Dept> queryAll();

}

DeptServiceImpl实现类

package com.it.service;


import com.it.dao.DeptDao;
import com.it.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class DeptServiceImpl implements DeptService{

   @Autowired
         private DeptDao deptDao;

   @Override
    public boolean addDept(Dept dept)
    {
        return deptDao.addDept(dept);
    }

    public Dept queryById(Long id)
    {
        return deptDao.queryById(id);
    }

    public List<Dept> queryAll()
    {
        return deptDao.queryAll();
    }




}

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

DeptMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper  namespace="com.it.dao.DeptDao">
    <insert id="addDept" parameterType="Dept">
       insert into dept(name,source)
       values (#{name},DATABASE())
    </insert>

    <select id="queryById" resultType="Dept"  parameterType="Long">
       select * from dept where id= #{id};
    </select>

    <select id="queryAll" resultType="Dept">
        select * from dept
    </select>

</mapper>

4.写启动类

package com.it;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

//启动类
@SpringBootApplication
@EnableEurekaServer
@EnableDiscoveryClient //服务发现
public class DeptProvide {

    public static void main(String[] args) {
        SpringApplication.run(DeptProvide.class,args);
    }
}

5.写一个用户 module

1.导依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.it</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-dept-user-80</artifactId>

<dependencies>
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>springclound-api</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>


</dependencies>


    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

2.配置端口(yml)
server:
port: 8002
3.写ConfigBean

package com.it.config;


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConfigBean {


    @Bean
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }



}

4.写相应的控制层,利用RestTemplate 调取其他moudel的方法

package com.it;

import com.it.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
public class DeptUserController {


    //消费者 不应该有service层
    //(url,实体:map,返回类型:Class<T> responseType)
    @Autowired
    private RestTemplate restTemplate;

    private static  final String REST_URL_PREFIX="http://localhost:8001";


    @RequestMapping("/user/dept/add")
    public boolean add(Dept dept)
    {
        return restTemplate.postForObject(REST_URL_PREFIX+"/dept/add",dept,Boolean.class);
    }



    @RequestMapping("/user/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id)
    {
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/get/"+id,Dept.class);
    }



    @RequestMapping("/user/dept/list")
    public List<Dept> list()
    {
        return restTemplate.getForObject(REST_URL_PREFIX+"/dept/list",List.class);
    }

    

}

5.写用户启动类

package com.it;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Deptuser80 {
    public static void main(String[] args) {
        SpringApplication.run(Deptuser80.class,args);
    }
}

热部署

1.子类加依赖

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-devtools</artifactId>
                    <scope>runtime</scope>
                    <optional>true</optional>
                </dependency>

2.父类加插件

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
        </plugins>
    </build>

3.开启自动编译
在这里插入图片描述
4.在子类 快捷键
ctrl+shift+alt+/ Registry
在这里插入图片描述
5.重启

Eureka服务注册与发现

1.开一个新的moudle 然后导包

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>com.it</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-Eureka-7001</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

</project>

2.配置yml

server:
  port: 7001
#Eureka配置
eureka:
  instance:
     hostname: localhost  #服务端实例名称
  client:
     register-with-eureka: false  #是否向eureka注册中心注册自己
     fetch-registry: false #false 自己为注册中心
     service-url:  #监控页面
       #设置关联   如果本身是 7001的 集群 下面就 连接http://eureka7001.com:7001/eureka/,http://eureka7002.com:7003/eureka/
       defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

3.写 启动类 测试

package com.it;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer    //接收别人注册
public class Eureka7001 {
    public static void main(String[] args) {
        SpringApplication.run(Eureka7001.class,args);
    }
}

集群

集群就相当于多个Eureka 然后让这些 moudle 模块相互关联
主要是让·1每个集群相互关联,导致有一个集群崩了,另外一个可以继续运行
直接配置多个Eureka
1.配置pom.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

2.配置yml

server:
  port: 7002
#Eureka配置
eureka:
  instance:
     hostname: localhost  #服务端实例名称
  client:
     register-with-eureka: false  #是否向eureka注册中心注册自己
     fetch-registry: false #false 自己为注册中心
     service-url:  #监控页面
       defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

3.写启动类

package com.it;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer    //接收别人注册
public class Eureka7002 {
    public static void main(String[] args) {
        SpringApplication.run(Eureka7002.class,args);
    }
}

CAP

c 一致性 a可用性 p分区容错性 满足3选2

Zookeeper保证的是cp 服务注册功能对可用性的要求高于一致性 当一个节点 死了的时候,会重新选择一个节点,如果几个节点数据量比较大,选举的时候花的时间就会长一点,30-120s且选举的时候集群是不可用的,选举的时候会导致服务器瘫痪
Eureka保证的是ap

Eureka 先保证可用
Eureka可以很好的应对网络故障导致的部分节点失去联系的情况,几个节点挂掉后 不影响别的节点的工作,挂掉一台后,会自动跳到另一台节点,只是有带你慢,如果85%的节点不能用的话就会认为 崩溃.
Eureka可以很好的应对网络故障导致的部分节点失去联系的情况,不会像zookeeper使整个注册服务 瘫痪

Zookeeper

1.启动类添加注解

@EnableDiscoveryClient //该注解用于向使用consul或者zookeeper作为注册中心时注册服务

2.导相关的依赖和配置等
3.注意zookeeeper的版本依赖包 和服务器上的 不一致,可能会出现依赖包问题
4.及时的 相应,当检测不到心跳以后 直接就关了 ,不会像eurke那样有自我保护机制.

Consul

1.安装运行Consul

consul agent -dev

2.前端页面
localhost:8500

ribbon

客户端实现负载均衡
负载均衡就是将用户的请求平摊分配搭配多个服务上,从而达到系统的HA(高可用)
轮询,随机 算法
1.导包

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
        <version>1.4.6.RELEASE</version>
    </dependency>
<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

2.配置yml

server:
  port: 8002
  #Eureka
eureka:
  client:
      register-with-eureka: false
      service-url:
        defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

3.在启动类上加注解
@EnableEurekaServer

4.在ConfigBean里面配置负载均衡
直接在RestTemplate上加上注解就行
@LoadBalanced //Ribbin

5.修改控制器里面的地址,修改成变量

    //Ribbon是一个变量,通过服务名来访问的,就是 获取提供者的地址
    //private static  final String REST_URL_PREFIX="http://localhost:8001";
    private static  final String REST_URL_PREFIX="SPRINGCLOUD-PROVIDER-DEPT";

自定义Ribbon算法(手写)

1.不能放在Component所扫描的本包和子包里面
2.启动类添加注解
3.在提供层(8000)增加负载均衡算法lb(自寻锁).
4.在消费层的config类里面取消LoadBalanced注解
5相应的lb接口来拿服务器的集群的台数 和实现类来自定义方法。

Feign负载均衡(OpenFeign)

feign一种声明式的web service客户端,集成了Ribbon 和Eureka,主要是社区,接口编程,调用微服务的2种方法
1.微服务的名字 ribbon
2.接口和注解 feign

只需要用接口 并且使用注解去配置在dao接口上标注mapper,并且一个微服务标注一个Feign注解即可

目录结构
.在这里插入图片描述
1.Feign是通过接口的方式来实现的,因此需要改变 api

在接口服务器中添加提供服务器中的接口

package com.it.service;


import com.it.pojo.Dept;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import java.util.List;

@Component
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT")
public interface DeptClientService {

  @GetMapping("/dept/get/{id}")
    public Dept queryById(@PathVariable("id") Long id);

    @GetMapping("/dept/list")
    public List<Dept> queryAll();

    @GetMapping("/dept/add")
    public Boolean addDept(Dept dept);


}

2.控制器中直接用注解去接收

package com.it;
import com.it.pojo.Dept;
import com.it.service.DeptClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;

@RestController
public class DeptUserController {
    @Autowired
    private DeptClientService service=null;

    @RequestMapping("/user/dept/add")
    public boolean add(Dept dept)
    {
        return this.service.addDept(dept);
    }
    @RequestMapping("/user/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id)
    {
           return this.service.queryById(id);
    }
    @RequestMapping("/user/dept/list")
    public List<Dept> list()
    {
       return this.service.queryAll();
    }
}

3.添加启动类 就可以测试

package com.it;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.it"})
@ComponentScan("com.it")
public class FeDeptuser80 {
    public static void main(String[] args) {
        SpringApplication.run(FeDeptuser80.class,args);
    }
}

4.只需要通过控制器的方法,就可以访问相应接口的方法,然后接口的方法去调用提供者的接口方法来实现功能

OpenFeign

1.建模块,yml,
2.启动类加注解 @EnableFeginClients
3.控制器写方法,方法调用接口
4.写接口和相应的config配置
5.openfeign 默认超时1s 可以在yml设置ribbon多一点
6.打印日志yml(打印接口)

logging:
  level:
    # feign日志以 debug 级别监控 com.atguigu.springcloud.service.PaymentFeignService 接口
    com.atguigu.springcloud.service.PaymentFeignService: debug

Hystrix服务熔断


雪崩: 用户去掉 客户端的服务,然后 一个服务会去调另外一个服务,多的几个服务,如果中间一个服务相应时间过长 或者不可用,然后就会在a服务有很多调用,占用很多资源,导致系统崩溃。然后就可以直接给他一个备用的服务,如果崩了 这个服务就只做一些熔断的措施,返回1用户这个服务崩了,然后继续下一层服务,保证服务尽可能正常运行。

Hystrix:处理分布式系统的延迟和容错的开源库,在分布式系统里面很多依赖不可避免调用失败超时等,Hystrix保证在一个依赖出问题的情况下,不会导致整体服务失败,避免连级故障,提高分布式系统弹性。

1.导入依赖

   <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

2.编写配置文件

server:
  port: 8009


#mybatis配置
mybatis:
  type-aliases-package: com.it.pojo
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml


#spring配置
spring:
  application:
    name: springcloud-provider-dept
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8
    username: root
    password: root

#Eureka配置

#Eureka配置
eureka:
  client:
    service-url:  #监控页面
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/ #发布位置, 可以设置集群 ,所有直接把所有集群 都加上去
  instance:
    instance-id: springcloud-dept-hystrix-8009  #修改eureka 上的默认描述信息

#info配置
info:
  app.name: song's first springcloud program
  company.name: song666

3.开启功能
model层等的书写,如上面的提供者。
然后写相应的控制器来开启熔断

package com.it.controller;


import com.it.pojo.Dept;
import com.it.service.DeptService;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

//提供restful服务
@RestController
public class DeptController {

    @Autowired
    private DeptService deptService;

    @GetMapping("/dept/get/{id}")
    @HystrixCommand(fallbackMethod = "hystrixGet")
    public Dept get(@PathVariable("id") Long id)
    {
        Dept dept=deptService.queryById(id);
        if (dept==null)
        {
            throw new RuntimeException("id=>"+id+"不存在该用户,或者信息没找到");
        }
        return dept;
    }

    //熔断
    public  Dept hystrixGet(@PathVariable("id") Long id)
    {
     return new Dept()
             .setId(id)
             .setName("id=>"+id+"没有对应的信息,null--@Hystrix")
             .setDb_source("no this database in Mysql");
    }
}

Hystrix服务降级

客户端 多提供一个服务,然后 当客户端服务器崩了时,提供一个服务 来进行降级处理,输出处理的结果。客户正常运行,

在这里插入图片描述
服务熔断:是服务降级的一种特殊情况,防止服务器雪崩采取的措施
服务降级:释放服务资源来保证核心业务正常高效运行。当某个服务熔断或关闭之前,服务不再被调用,此时在客户端准备一个FallbackFactory,返回一个默认值,整体的服务水平下降。

实现步骤:
1.多设置一个服务端,在服务端设置降级 (端口和用户相同,此时的feign端 就相当于是 用户,不需要再开启一个用户端)

server:
  port: 8002
  #Eureka
eureka:
    client:
      register-with-eureka: false
      service-url:
        defaultZone: http://localhost:7002/eureka/,http://localhost:7001/eureka/
      #  defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/


#feign 开启降级feign,hystrix
feign:
  hystrix:
    enabled: true

2.服务端启动类上加上 降级的注解

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients(basePackages = {"com.it"})
@ComponentScan("com.it")
public class FeDeptuser80 {
    public static void main(String[] args) {
        SpringApplication.run(FeDeptuser80.class,args);
    }
}

3.在接口端 设置对应的降级控制器

package com.it.service;
import com.it.pojo.Dept;
import feign.hystrix.FallbackFactory;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
import java.util.List;
//降级
@Component
public class DeptClientServiceFallbackFactory implements FallbackFactory {
    public DeptClientService create(Throwable throwable)
    {
        return new DeptClientService() {
            @Override
            public Dept queryById(Long id) {
                return new Dept()
                        .setId(id)
                        .setName("id=>"+id+"没有对应的信息,客户端提供降级的信息,这个服务器现在已经关闭")
                        .setDb_source("空,没有数据");
            }
            @Override
            public List<Dept> queryAll() {
                return null;
            }

            @Override
            public Boolean addDept(Dept dept) {
                return null;
            }
        };
    }
}

4.接口端的接口开启降级注解


@Component
@FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT",fallbackFactory = DeptClientServiceFallbackFactory.class)
public interface DeptClientService {

  @GetMapping("/dept/get/{id}")
    public Dept queryById(@PathVariable("id") Long id);

    @GetMapping("/dept/list")
    public List<Dept> queryAll();

    @GetMapping("/dept/add")
    public Boolean addDept(Dept dept);


}

5.测试

当客户 访问服务的时候,提供端 8001如果崩了的话,就会直接进行服务降级,进行提示。
在这里插入图片描述

Dashboard流监控

1.新建一个模块然后导包 还有 配置端口

  <dependencies>
        <!--完善监控信息-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--hystrix 监控-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

        <!--Rinbbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <!--eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>springclound-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>

2.写启动类 开启 监控页面

package com.it;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

@SpringBootApplication
@EnableHystrixDashboard  //开启监控页面
public class DeptUserDashboard_9001 {

    public static void main(String[] args) {

        SpringApplication.run(DeptUserDashboard_9001.class, args);
    }
}

3.测试
在这里插入图片描述
4.在提供服务的服务端 中 添加 相应的监控依赖

  <!--完善监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

5.然后在服务端启动类上添加监控

//启动类
@SpringBootApplication
@EnableEurekaServer
@EnableDiscoveryClient //服务发现
public class DeptProvide {

    public static void main(String[] args) {
        SpringApplication.run(DeptProvide.class,args);
    }

    //增加一个servlet
    @Bean
    public ServletRegistrationBean  hystrixMetricsStreamServlet()
    {
     ServletRegistrationBean registrationBean=new ServletRegistrationBean(new HystrixMetricsStreamServlet());
     registrationBean.addUrlMappings("/actuator/hystrix.stream");
     return registrationBean;
    }
}

6.在 监控页面 添加相应的地址 也就是 上面启动类上的流 然后就可以进行监控
在这里插入图片描述
7.在提供服务端 的控制器内 需要监控的方法上加上 @HystrixCommand注解

在这里插入图片描述

路由网关Zuul

路由,代理,过滤

路由的请求: 外部的请求转发到具体的微服务实例上,用来跳转的
路由的过滤: 对七八个球的处理过程进行干预,校验服务聚合

Zuul和Eureka进行整合,把Zuul自身注册为Eureka下的应用,同时从Eureka获得其他微服务的消息,访问微服务也是用Zuul跳转

1.新建模块,导包

   <!--zuul-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>

2.写控制器 加相应的 注解

@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication_9527 {

    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication_9527.class,args);
    }

}

3.配置yml

server:
  port: 9528

spring:
  application:
    name: springcloud-zuul

#Eureka
eureka:
  client:
    service-url:
         defaultZone: http://localhost:7002/eureka/,http://localhost:7001/eureka/
  instance:
    instance-id: zuul9527.com
    prefer-ip-address: true

info:
  app.name: song
  company.name: aaa

zuul:
  routes:
    mydept.serviceId: springcloud-provider-dept  #这里其实就是提供者的服务名字  http://localhost:9528/springcloud-provider-dept/dept/get/2
    mydept.path: /mydept/**   #代替上面的路径   http://localhost:9528/mydept/dept/get/3
  ignored-services: "*"       #不在使用服务的那个路径  只能使用指定的
  prefix: /song         #设置公共前缀    http://localhost:9528/song/mydept/dept/get/3

4.直接进行访问
在这里插入图片描述

Gateway网关

Springcloud Gateway是Spring Cloud生态系统的网关,来替代Zuul, 在SpringCloud2.0以上没有对应新版本zuul2.0来集成。为了提高性能,SpringCloud Gateway基于Webflux框架实现,而Webflux底层是采用高性能的Reactor模式通信框架Netty。
zuul1是阻塞型IO,也就是servlet
Gateway是非阻塞的
组成
1.Route(路由)
2.Predicate(断言) 匹配HTTP请求头或请求参数
3.Filter(过滤)
配置
1.yml中配置
2.注入到容器
断言
1.yml进行配置
过滤器
1.自定义过滤器,

package com.atguigu.springcloud.filter;


import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;

@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("***********come in MyLogGateWayFilter:  " + new Date());

        // 获取请求参数中的 uname
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");

        if (uname == null) {
            log.info("*******用户名为null,非法用户,o(╥﹏╥)o");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }

        return chain.filter(exchange);
    }

    /**
     * 加载过滤器顺序,数字越小优先级越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}

Springcloud Config分布式配置中心

1.优点:
1.集中管理配置
2.不同环境不同配置,动态更新
3.把配置信息以REST接口的形式暴露
1.动态配置管理
1.服务端:3344 就
2.客户端

config手动刷新

1.导b
2.暴露监控端口(yml加配置)

# 暴露监控端点 否则 curl -X POST "http://localhost:3355/actuator/refresh" 不可使用
management:
  endpoints:
    web:
      exposure:
        include: "*"

3.config控制器加上 注解 @RefreshScope
4.执行命令 curl -X POST “http://localhost:3355/actuator/refresh” 进行手动刷新

消息总线(Spring Cloud Bus)

作用:分布式执行器,用于广播状态的更改,事件推送等,相当于微服务间的通信通道
1.差异形刷新
2.动态刷新

RabbitMQ

设计思想
1.利用消息总线触发一个服务端ConfigServe 配置中心 的/bus/refresh端点,而刷新所有客户端的配置,
在这里插入图片描述
2.利用消息总线出发一个客户端/bus/refresh而刷新所有客户端配置
在这里插入图片描述
1.安装链接添加链接描述
配置
1.导包

        <!--添加消息总线RabbitMQ支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bus-amqp</artifactId>
        </dependency>

2.yml添加支持

server:
  port: 3366

spring:
  application:
    name: config-client
  cloud:
    #Config客户端配置
    config:
      label: main #分支名称
      name: config #配置文件名称
      profile: dev #读取后缀名称   上述3个综合:master分支上config-dev.yml的配置文件被读取http://config-3344.com:3344/master/config-dev.yml
      uri: http://localhost:3344 #配置中心地址

#服务注册到eureka地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka

# 暴露监控端点
management:
  endpoints:
    web:
      exposure:
        include: "*"

#rabbitmq相关配置 15672是Web管理界面的端口;5672是MQ访问的端口
rabbitmq:
  host: localhost
  port: 15672
  username: guest
  password: guest

4.开启rabbitMQ启动
5.执行命令 curl -X POST “http://localhost:3344/actuator/refresh” 进行手动刷新

动态化通知
全局通知 curl -X POST “http://localhost:3344/actuator/bus-refresh”
局部通知 curl -X POST “http://localhost:3344/actuator/bus-refresh/config-client:3366” 微服务名+端口号

SpringCloud 连接github

在这里插入图片描述

1.本地连接上github
可以去看我的这个博客来链接git和github操作
2.传送到github上的appliaction配置

spring:
  profiles:
    active:

---
spring:
  profiles: dev
  application:
   name: springcloud-config-dev

---
spring:
  profiles: test
  application:
     name: springcloud-config-test

3.开始配连接github的模块来连接远程
1.导报

<dependencies>
        <!--config-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
    </dependencies>

1.在yml里面配置自己的远程地址

server:
  port: 3344

spring:
  application:
    name: springcloud-config-server
    #连接远程仓库
  cloud:
    config:
     server:
       git:
         uri: https://github.com/project-oys/springcloud.git  #http的
         

2.启动类去连接

@SpringBootApplication
@EnableConfigServer
@EnableEurekaClient
public class config_serve3344 {
    public static void main(String[] args) {
        SpringApplication.run(config_serve3344.class,args);
    }
}

4.直接在后面加上要读的文件就可以读取

http://localhost:3344/main/application-dev.yml

客户端连接github配置
1.在github上传入客户端的相关配置

spring:
  profiles:
    active: dev
---
server:
  port:8201
#spring配置
spring:
 profiles: dev
 application:
    name: springcloud-provider-dept
#Eureka配置
eureka:
  client:
    service-url:  #监控页面
      defaultZone: http://localhost:7001/eureka/  #发布位置, 可以设置集群 ,所有直接把所有集群 都加上去
---
server:
  port:8201
#spring配置
spring:
 profiles: test
 application:
    name: springcloud-provider-dept
#Eureka配置
eureka:
  client:
    service-url:  #监控页面
      defaultZone: http://localhost:7001/eureka/  #发布位置, 可以设置集群 ,所有直接把所有集群 都加上去

2.开启客户端模块并且导依赖

  <dependencies>
        <!--客户端是 启动config-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.6.RELEASE</version>
        </dependency>
    </dependencies>

3.配置bootstrap.yml(系统级别的配置)

spring:
  cloud:
    config:
      name: config-client #需要获取的文件
      profile: dev	
      label: main
      uri: http://localhost:3344

4.配置application.yml

spring:
  application:
   name: springcloud-config-client-3355

5.调一个控制层来调取github上获取的东西

package com.it.controller;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConfigClientController {

  @Value("${spring.application.name}")
  private String applicationName;

  @Value("${eureka.client.service-url.defaultZone}")
  private String eurekaServer;

  @Value("${spring.application.name}")
  private String port;

  @RequestMapping("/config")
  public String getConfig()
  {
      return "application.name"+applicationName+"eureka"+eurekaServer+"port"+port;
  }



}

6.启动类测试

package com.it;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ConfigClient_3355 {

    public static void main(String[] args) {
        SpringApplication.run(ConfigClient_3355.class,args);
    }
}

SpringCloud Stream消息驱动

常见中间件:1.ActiveMQ 2.RabbitMQ 3.RocketMQ 4.Kafka
作用: 比如 后端 和 后面大数据平台 可能会有很多 后端用RabbitMQ 大数据用Kafka 就会有差异, SpringCloud Stream是一个构建消息驱动微服务的框架,可以屏蔽底层中间件的差异,统一消息的编程模型。
原理:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值