springcloud笔记(整合Eureka、Ribbon、Feign、Hystrix、Zuul)

狂神说

环境:

SpringCloud: Hoxton.SR9
SpringBoot:2.3.5.RELEASE
其他依赖:2.2.6.RELEASE

相关依赖

服务者:pring-cloud-starter-netflix-eureka-client
Eureka:spring-cloud-starter-netflix-eureka-server
消费者+Ribbon:spring-cloud-starter-netflix-eureka-client
spring-cloud-starter-netflix-ribbon
Feign: spring-cloud-starter-openfeign
Hystrix:spring-cloud-starter-netflix-hystrix
spring-cloud-starter-netflix-hystrix-dashboard
zuul:spring-cloud-starter-netflix-zuul

数据库(这里要建三个不同的数据库,模拟负载均衡)

sql

CREATE TABLE `dept` (
  `dno` bigint(20) NOT NULL AUTO_INCREMENT,
  `dname` varchar(60) DEFAULT NULL,
  `db_source` varchar(60) DEFAULT NULL,
  PRIMARY KEY (`dno`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COMMENT='部门表';

数据

INSERT INTO dept (dname, db_source)VALUES ('开发部',DATABASE());
INSERT INTO dept (dname, db_source)VALUES ('市场部',DATABASE());
INSERT INTO dept (dname, db_source)VALUES ('研发部',DATABASE());
INSERT INTO dept (dname, db_source)VALUES ('人事部',DATABASE());

数据库
在这里插入图片描述

父工程(父依赖)

 <!--    打包方式-->
    <packaging>pom</packaging>

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

    <dependencyManagement>
        <dependencies>
            <!-- springcloud依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

springcloud-api

依赖:

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

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
        <version>2.2.6.RELEASE</version>
    </dependency>
</dependencies>

实体类(供其他服务调用)

@Data
@NoArgsConstructor
@Accessors(chain = true) //支持链式写法
public class Dept {
    private Long dno;
    private String dname;
    private String db_source;

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

整合Eureka

两个组件:Eureka ServerEureka Client。

Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。

Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。

容灾机制(没啥用)
在应用启动后,将会向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90秒)。

服务提供者(springcloud-provide-dept-9001)

依次搭建三个,连接不同的数据库,模拟负载均衡

包结构

在这里插入图片描述

依赖

<dependency>
            <groupId>com.sun</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--数据库-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>


        <!-- Eureka -->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>


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

application.yml

server:
  port: 9001

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


#配置
spring:
  datasource:
    username: root
    password: qwe123456
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
  application:
    name: spring-clout-provide-dept

##eureka配置,将服务提供者注册到注册中心
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springclout-provide-dept-9001
#info配置
info:
  app.name: ajie-spring-cloud
  company.name: localhost:9001

代码(mybatis)

Mapper层
DeptMapper

@Mapper
@Repository
public interface DeptMapper {
    Boolean insert(Dept dept);
    Dept getById(Long dno);
    List<Dept> all();
}

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">

<!-- namespace=绑定一个对应的Dao/Mapper接口 -->

<mapper namespace="com.sun.mapper.DeptMapper">

    <insert id="insert" parameterType="Dept">
        insert into db01.dept(dname, db_source)
        values (#{dname},DATABASE());
    </insert>

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

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


</mapper>

service层

DeptService接口

public interface DeptService {
    Boolean insert(Dept dept);

    Dept getById(Long dno);

    List<Dept> all();
}

实现类

@Service
public class DeptServiceImpl implements DeptService{

    @Autowired
    DeptMapper deptMapper;


    @Override
    public Boolean insert(Dept dept) {
        return deptMapper.insert(dept);
    }

    @Override
    public Dept getById(Long dno) {
        return deptMapper.getById(dno);
    }

    @Override
    public List<Dept> all() {
        return deptMapper.all();
    }
}

controller层

DeptController

@RestController
public class DeptController {


    @Autowired
    DiscoveryClient client;

    @Autowired
    DeptServiceImpl service;

    @PostMapping("/insert")
    public boolean insert(Dept dept){
        return service.insert(dept);
    }

    @GetMapping("/ById/{dno}")
    public Dept get(@PathVariable("dno") Long dno){
        Dept byId = service.getById(dno);
        return byId;
    }

    @GetMapping("/")
    public List<Dept> all(){
        return service.all();
    }

    //得到注册中心微服务的信息
    @GetMapping("/discovery")
    public Object discovery(){
        //获取微服务列表的清单
        List<String> services = client.getServices();
        System.out.println("微服务清单:"+services);

        //获取具体微服务信息,通过id进行查询
        List<ServiceInstance> instances = client.getInstances("SPRING-CLOUT-PROVIDE-DEPT-9000");
        for (ServiceInstance instance : instances) {
            System.out.println(
                    instance.getHost()+"\t"+
                    instance.getPort()+"\t"+
                    instance.getUri()+"\t"+
                    instance.getServiceId()
            );
        }
        return this.client;
    }
}

然后再主类上开始

@SpringBootApplication
@EnableEurekaClient //开启Eureka注解,启动之后服务提供者就会自动注册到注册中心
public class SpringcloudProvideDept9001Application {

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

运行就会循环寻找注册中心注册

注册中心(springcloud-eureck-7001)

这个也可以搭建多个,模拟一个注册中心崩掉之后还有其他注册中心进行服务

Eureka的注册中心是要自己配置

依赖

<!--eureka服务端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

application.yml

server:
  port: 7001

#Eureka配置
eureka:
  instance:
    hostname: eureka7001.com
  client:
    register-with-eureka: false # 表示是否向eureka注册中心注册自己
    fetch-registry: false   #fetch-registry如果为false,表明自己为注册中心
    service-url: # 注册中心
      #单机:http://${eureka.instance.hostname}:${server.port}/eureka/
      #集群(关联)
      defaultZone: http://eureka7003.com:7003/eureka/,http://eureka7002.com:7002/eureka/

然后再主类上开启eureka服务就是ok了
一个注册中心就搭好了

@SpringBootApplication
@EnableEurekaServer //开启eureka服务
public class SpringcloudEureck7001Application {

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

}

效果
在这里插入图片描述

服务消费者(springcloud-consume-8011)

通过注册中心调用服务提供的service层
依赖

<dependency>
            <groupId>com.sun</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <!--eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

application.yml

#Eureka 配置
eureka:
  client:
    register-with-eureka: false #不向注册中心注册自己(消费者)
    service-url:
      #分别注册
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
server:
  port: 8011

代码

config配置
实现负载均衡的一些算法(轮询和随机)

@Configuration
public class DeptConsumerConfig {
    // 配置负载均衡实现RestTemplate
    @Bean
    @LoadBalanced //开启负载均衡 默认轮询算法
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

    @Bean //随机算法
    public IRule rom() {
        return new RandomRule();
    }

}

controller层


@RestController
public class DeptConsumerController {


    //通过restTemplate 发送http请求
    @Autowired
    private RestTemplate restTemplate; //提供多种便捷访问远程http服务的方法,简称Restful服务模板

    private static final String REST_URL_PREFIX = "http://SPRING-CLOUT-PROVIDE-DEPT";

    @RequestMapping("/all")
    public List<Dept> all() {
        return restTemplate.getForObject(REST_URL_PREFIX, List.class);

    }

    @RequestMapping("/dno/{dno}")
    public Dept getById(@PathVariable("dno") Long dno) {
        return restTemplate.getForObject(REST_URL_PREFIX + "/ById/" + dno, Dept.class);
    }

    @PostMapping("/insert")
    public Boolean insert(Dept dept) {
        return restTemplate.postForObject(REST_URL_PREFIX + "/insert", dept, Boolean.class);

    }
}

然后再主类上开启

@SpringBootApplication
@EnableEurekaClient
public class SpringcloudConsume8011Application {

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

}

运行即可
效果:
在这里插入图片描述

整合ribbon

依赖

<!--ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>

上面的服务提供者依葫芦画瓢搭建多个,然后连接不同的数据库,都注册到注册中心,然后服务消费者多次调用,才看数据库,就差不多了

整合Feign

这东西我不会,一直报404,给我整抑郁了

整合Hystrix(springcloud-provide-dept-hystrix-9001)

和上面的服务提供差不多,不过这个加了熔断机制

包结构

在这里插入图片描述

依赖

<dependency>
            <groupId>com.sun</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--数据库-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>


        <!-- Eureka -->
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>


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

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

application.yml

server:
  port: 9001

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


#配置
spring:
  datasource:
    username: root
    password: qwe123456
    url: jdbc:mysql://localhost:3306/db01?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
  application:
    name: spring-clout-provide-dept


##eureka配置,将服务提供者注册到注册中心
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springclout-provide-dept-hystrix-9001
    prefer-ip-address: true #设置为true 可以显示ip



#info配置
info:
  app.name: ajie-spring-cloud
  company.name: localhost:9001

代码:

Mapper层和Service层都一样的,就略
controller

@RestController
public class DeptController {

    @Autowired
    DeptServiceImpl service;


    @GetMapping("/ById/{dno}")
    @HystrixCommand(fallbackMethod = "hystrixGet")
    public Dept get(@PathVariable("dno") Long dno){
        Dept byId = service.getById(dno);

        if(byId ==null){
            throw new RuntimeException("dno=>"+dno+"不存在");
        }
        return byId;
    }

    //    //备选
    public Dept hystrixGet(@PathVariable("dno")Long dno){
        return new Dept()
                .setDno(dno)
                .setDname("dno=>"+dno+"不存在")
                .setDb_source("no this database in MYSQL");
    }


    @GetMapping("/")
    public List<Dept> all(){
        return service.all();
    }
}

在主类上开启

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker //添加对熔断的支持
public class SpringcloudProvideDeptHystrix9001Application {

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

效果:
正常
在这里插入图片描述
模拟出错(查询不存在的值)
在这里插入图片描述

监控(springcloud-consume-hystrix-dashboard-8013)

hysrix自带的流量监控,不过只能对加了熔断注解的方法继续监视

依赖

 <dependency>
            <groupId>com.sun</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <!--eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>


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

application.yml
确保监控中心能寻找到流

# 添加hystrix监控配置
hystrix:
  dashboard:
    proxy-stream-allow-list: "*"

在主类上开始监控

@SpringBootApplication
@EnableHystrixDashboard //开启监控
public class SpringcloudConsumeHystrixDashboard8013Application {

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

}

一个监控中心就搭建完了
启动运行http://localhost:8013/hystrix
效果:
在这里插入图片描述
在添加熔断的主类下添加以下代码,方便被监控

// 增加servlet监控 只有hystrix的依赖才能被监控
    @Bean
    public ServletRegistrationBean hystrixMetricsStreamServlet() {
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
        registrationBean.addUrlMappings("/actuator/hystrix.stream");
        return registrationBean;
    }

这里只能监控添加熔断的服务端
在这里插入图片描述

整合Zuul(springcloud-zuul-6001)

通过一个同意的入口进行访问

依赖

<dependency>
            <groupId>com.sun</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!--ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <!--eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>


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

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

application.yml

server:
  port: 6001

spring:
  application:
    name: springcloud-zuul

#去那些注册中心发现
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: springcloud-zuul-6001
    prefer-ip-address: true
info:
  app.name: ajie
  company.naeme: ajie-springcloud

#zuul配置,把微服务名称进行替换,防止暴露
zuul:
  routes:
    mydept.serviceId: spring-clout-provide-dept
    mydept.path: /mydept/**

  ignored-services: spring-clout-provide-dept # 不能使用该路径访问 隐藏微服务

在主类上开启

@SpringBootApplication
@EnableZuulProxy //开启zuul路由
public class SpringcloudZuul6001Application {

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

在这里插入图片描述

通过统一的http://localhost:6001/mydept/ById/3进行访问,在application.yml配置文件中进行设置
在这里插入图片描述
差不多就是这些了

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值