SpringCloud

1.Spring模块

pom文件

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.coco</groupId>
    <artifactId>springcloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <modules>
<!--        模块只管pojo-->
        <module>springcloud-api</module>
        <module>springcloud-provider-dept-8001</module>
        <module>springcloud-consumer-dept-80</module>
        <module>springcloud-eureka-7001</module>
        <module>springcloud-zuui-9527</module>
        <module>vue</module>
    </modules>

    <packaging>pom</packaging>
    <properties>
        <java.version>1.8</java.version>
        <junit.version>4.12</junit.version>
        <lombok.version>1.18.24</lombok.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2021.0.4</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.7.3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.30</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>1.2.13-SNSAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.2</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
            <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>
</project>

2.api模块-只负责pojo

pom文件

<?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>springcloud</artifactId>
        <groupId>com.coco</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-api</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
<!--        父依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
<!--        自己的依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
    </dependencies>


</project>

编写pojo类

package com.coco.springcloud.pojo;

import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;

import java.io.Serializable;

@Accessors(chain = true)
@Getter
@Setter
@ToString
@NoArgsConstructor
public class Dept implements Serializable {

  private long deptno;
  private String dname;
  private String db_source;

}

3.服务提供者

application.yml

server:
  port: 8001
mybatis:
  type-aliases-package: com.coco.springcloud.pojo
  config-location: classpath:mybatis/mybatis-config.xml
  mapper-locations: classpath:mybatis/mapper/*.xml
spring:
  application:
    name: springcloud-provider-TiGongZhe
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/corainld?useUnicode=true&characterEncoding=utf-8
    username: root
    password: 123456

编写mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>

编写dao层

package com.coco.springcloud.dao;

import com.coco.springcloud.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();
}

编写service层

package com.coco.springcloud.service;

import com.coco.springcloud.pojo.Dept;

import java.util.List;

public interface DeptService {
    public boolean addDept(Dept dept);

    public Dept queryById(Long id);

    public List<Dept> queryAll();
}
package com.coco.springcloud.service;

import com.coco.springcloud.dao.DeptDao;
import com.coco.springcloud.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);
    }

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

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

编写mapper

<?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.coco.springcloud.dao.DeptDao">
    <insert id="addDept" parameterType="Dept">
        insert into dept (dname, db_source)
        values (#{dname}, DATANASE());
    </insert>

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

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

编写controller层

package com.coco.springcloud.controller;

import com.coco.springcloud.pojo.Dept;
import com.coco.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Controller;
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;

@RestController
public class DeptController {
    @Autowired
    private DeptService deptService;

    @Autowired
    private DiscoveryClient discoveryClient;

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

    @HystrixCommand(fallbackMethod = "hystrixGet")
    @GetMapping("/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
        Dept dept = deptService.queryById(id);
        System.out.println(dept);

        if (dept == null) {
            throw new RuntimeException("id=>" + id + ", 不存在该用户");
        }
        return dept;
    }

    public Dept hystrixGet(@PathVariable("id") Long id) {
        return new Dept().setDeptno(id).setDname("id=>" + id + ", 不存在该用户").setDb_source("no Databased");
    }

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

    @GetMapping("dept/discovery")
    public Object discovery() {
        //获取微服务名单

        List<String> services = discoveryClient.getServices();
        System.out.println("服务清单:" + services);

        List<ServiceInstance> instances = discoveryClient.getInstances("springcloud-provider提供者");
        instances.forEach(x->{
            System.out.println(x.getHost());
            System.out.println(x.getPort());
            System.out.println(x.getUri());
            System.out.println(x.getServiceId());
        });

        return this.discoveryClient;
    }
}

编写启动类,启动访问:http://localhost:8001/dept/list

package com.coco.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;

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

3.服务消费者-远程调用

pom文件

<?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>springcloud</artifactId>
        <groupId>com.coco</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

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

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.coco</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>0.0.1-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>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-loadbalancer</artifactId>
            <version>2.3.0</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-ribbon</artifactId>
            <version>2.2.10.RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

application.yml

server:
  port: 80

注册一个restTemplate bean注入到controller层


import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConfigBean {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public IRule myrule() {
        return new RandomRule();
    }
}

编写controller层

package com.coco.springcloud.controller;

import com.coco.springcloud.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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 org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
public class DeptConsumerController {
    //消费者不该有service
    //RestTemplate供直接调用
    //public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)
    //通过configBean注入
    @Autowired
    private RestTemplate restTemplate;

//    private static final String Rest_url_prefix = "http://localhost:8001";
    private static final String Rest_url_prefix = "http://SPRINGCLOUD-PROVIDER-TIGONGZHE";

    @GetMapping("/consumer/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
//        Dept dept = deptService.queryById(id);
        Dept dept = restTemplate.getForObject(Rest_url_prefix + "/dept/get/" + id, Dept.class);
        System.out.println(dept);

        return dept;
    }

    @GetMapping("/consumer/list")
    public List<Dept> queryAll() {
        return restTemplate.getForObject(Rest_url_prefix + "/dept/list", List.class);
    }

    @PostMapping("/consumer/add")
    public boolean addDept(Dept dept) {
        return restTemplate.postForObject(Rest_url_prefix + "/dept/add", dept, boolean.class);
    }


}

编写启动类,启动访问:http://localhost/consumer/list

package com.coco.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;

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

4.将远程注册中心从zookeeper变成Eureka,舍弃一致性,实现可用性

pom文件

<?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>springcloud</artifactId>
        <groupId>com.coco</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-eureka-7001</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

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

    </dependencies>
</project>

application.yml

server:
  port: 7001
eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false #是否向eureka注册中心注册自己
    fetch-registry: false #false表示自己为注册中心
    service-url: #与注册中心交互
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
      #http://127.0.0.1:7002/eureka/,http://127.0.0.1:7003/eureka/
      #this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");

编写启动类,启动访问:http://localhost:7001/

package com.coco.springcloud;

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

@SpringBootApplication
@EnableEurekaServer //表示为服务端的启动类,可以接受别人注册进来
public class Eureka_7001 {
    public static void main(String[] args) {
        SpringApplication.run(Eureka_7001.class, args);
    }
}

服务提供者配置注册中心地址

pom中增加依赖

<!--服务提供者配置Eureka注册中心依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
<!--Eureka界面上的status监控描述依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

application.yml中增加配置

#服务端配置Eureka注册中心地址
eureka:
  client:
    service-url:
      defaultZone: http://localhost:7001/eureka/,http://localhost:7002/eureka/,http://localhost:7003/eureka/
  instance:
    instance-id: spri-pro-8001 #status描述信息
    prefer-ip-address: true #隐藏ip


info:
  app.name: 监控信息 #点击status进入
  company.name: 996

management:
  endpoints:
    web:
      exposure:
        include: "*"
  info:
    env:
      enabled: true

启动类中添加注解

@EnableEurekaClient //添加后服务启动时自动注册进Eureka中
@EnableDiscoveryClient//向controller中注册discovery获取配置信息

获取配置方法

//获取一些配置信息
    @Autowired
    private DiscoveryClient discoveryClient;

    @GetMapping("dept/discovery")
    public Object discovery() {
        //获取微服务名单

        List<String> services = discoveryClient.getServices();
        System.out.println("服务清单:" + services);

        List<ServiceInstance> instances = discoveryClient.getInstances("springcloud-provider-TiGongZhe");
        instances.forEach(x->{
            System.out.println(x.getHost());
            System.out.println(x.getPort());
            System.out.println(x.getUri());
            System.out.println(x.getServiceId());
        });

        return this.discoveryClient;
    }

添加集群,将defaultZone从单机改为集群

server:
  port: 7001
eureka:
  instance:
    hostname: eureka7001.com
  client:
    register-with-eureka: false #是否向eureka注册中心注册自己
    fetch-registry: false #false表示自己为注册中心
    service-url: #与注册中心交互
      defaultZone: http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
      #单机:http://${eureka.instance.hostname}:${server.port}/eureka/
      #默认:this.serviceUrl.put("defaultZone", "http://localhost:8761/eureka/");

服务提供者修改defaultZone

#服务端配置Eureka注册中心地址
eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: status
    prefer-ip-address: true #自我保护机制,不推荐关闭

服务消费者

添加Eureka依赖

<!--eureka配置-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>

添加Eureka配置

server:
  port: 80
eureka:
  client:
    register-with-eureka: false
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

 启动类添加注解

@EnableEurekaClient

5.Ribbon-为服务客户端做一些简单的负载均衡:用某种规则为客户端平摊分配到多台服务器上,从而实现高可用

进程式负载均衡,将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选出一个合适的服务器

pom文件添加Ribbon依赖

<!--Ribbon配置-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-ribbon</artifactId>
            <version>2.2.10.RELEASE</version>
            <scope>compile</scope>
        </dependency>
<!--负载均衡依赖-->
        <dependency>
            <groupId>com.netflix.ribbon</groupId>
            <artifactId>ribbon-loadbalancer</artifactId>
            <version>2.3.0</version>
            <scope>compile</scope>
        </dependency>

ConfigBean中添加Ribbon注解,并设置负载均衡规则

package com.coco.springcloud.config;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ConfigBean {

    @Bean
    @LoadBalanced //开启负载均衡注解
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public IRule myrule() {
        return new RandomRule();
    }
}

controller中将固定服务器地址修改为服务器名

package com.coco.springcloud.controller;

import com.coco.springcloud.pojo.Dept;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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 org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
public class DeptConsumerController {
    //消费者不该有service
    //RestTemplate供直接调用
    //public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables)

    @Autowired
    private RestTemplate restTemplate;

    //无Ribbon通过固定地址请求
    //private static final String Rest_url_prefix = "http://localhost:8001";

    //有Ribbon通过服务名请求
    private static final String Rest_url_prefix = "http://SPRINGCLOUD-PROVIDER-TIGONGZHE";

    @GetMapping("/consumer/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
//        Dept dept = deptService.queryById(id);
        Dept dept = restTemplate.getForObject(Rest_url_prefix + "/dept/get/" + id, Dept.class);
        System.out.println(dept);

        return dept;
    }

    @GetMapping("/consumer/list")
    public List<Dept> queryAll() {
        return restTemplate.getForObject(Rest_url_prefix + "/dept/list", List.class);
    }

    @PostMapping("/consumer/add")
    public boolean addDept(Dept dept) {
        return restTemplate.postForObject(Rest_url_prefix + "/dept/add", dept, boolean.class);
    }


}

启动并访问:http://localhost/consumer/list

自定义规则组件

package com.coco.springcloud.myrule;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class myRule {
    @Bean
    public IRule myrule() {
        return new RandomRule();
    }
}

启动类添加注解

@RibbonClient(name = "springcloud-provider-TiGongZhe",configuration = myRule.class)

6.Feign-通过创建接口并使用注解实现负载均衡

api中添加服务接口

package com.coco.springcloud.service;

import com.coco.springcloud.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 org.springframework.web.bind.annotation.PostMapping;

import java.util.List;

@Component
public interface DeptClientService {

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

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

    @PostMapping("/dept/add")
    boolean addDept(Dept dept);

    @GetMapping("/dept/json")
    String js(String s);
}

服务客户端

pom文件添加Feign依赖

<!--Feign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>

controller层添加注解实现接口

package com.coco.springcloud.controller;

import com.coco.springcloud.pojo.Dept;
import com.coco.springcloud.service.DeptClientService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;

@RestController
public class DeptConsumerController {

    //不再通过restTemplate实现
    @Autowired
    private RestTemplate restTemplate;

    //通过Feign实现
    @Autowired
    private DeptClientService deptClientService;

//    private static final String Rest_url_prefix = "http://localhost:8001";
    //加了ribbon后
//    private static final String Rest_url_prefix = "http://SPRINGCLOUD-PROVIDER-TIGONGZHE";

    @GetMapping("/consumer/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
//        Dept dept = deptService.queryById(id);
//        Dept dept = restTemplate.getForObject(Rest_url_prefix + "/dept/get/" + id, Dept.class);
        return this.deptClientService.queryById(id);
    }

    @GetMapping("/consumer/list")
    public List<Dept> queryAll() {
        return this.deptClientService.queryAll();
    }

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

    @GetMapping("/consumer/js")
    public String json(Dept dept) throws JsonProcessingException {
        dept.setDeptno(1).setDname("111").setDb_source("cococo");

        ObjectMapper mapper = new ObjectMapper();
        String str = mapper.writeValueAsString(dept);

        return str;
    }


}

启动类添加注解

package com.coco.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

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

7.Hystrix-服务熔断机制

服务客户端

pom文件添加hystrix依赖

<!--服务熔断依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>

熔断备用方法

    @HystrixCommand(fallbackMethod = "hystrixGet")
    @GetMapping("/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
        Dept dept = deptService.queryById(id);
        System.out.println(dept);

        if (dept == null) {
            throw new RuntimeException("id=>" + id + ", 不存在该用户");
        }
        return dept;
    }

    //抛出异常后执行备选方案
    public Dept hystrixGet(@PathVariable("id") Long id) {
        return new Dept().setDeptno(id).setDname("id=>" + id + ", 不存在该用户").setDb_source("no Databased");
    }

启动类添加hystrix注解

package com.coco.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;

@SpringBootApplication
@EnableEurekaClient //添加后服务启动时自动注册进Eureka中
@EnableDiscoveryClient//向controller中注册discovery获取配置信息
@EnableHystrix//开启熔断
public class DeptProvider_8002 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8002.class, args);
    }
}

服务降级

api中添加工厂类

package com.coco.springcloud.service;

import com.coco.springcloud.pojo.Dept;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

//服务降级,服务全部停止时批量处理熔断
@Component
public class DeptClientFallbackFactory implements FallbackFactory {

    @Override
    public DeptClientService create(Throwable cause) {
        return new DeptClientService() {
            @Override
            public Dept queryById(Long id) {
                return new Dept().setDeptno(id)
                        .setDname("没有对应信息,服务已经关闭")
                        .setDb_source("no database");
            }

            @Override
            public List<Dept> queryAll() {
                Dept dept = new Dept().setDname("all server down").setDb_source("null");
                List a = new ArrayList();
                a.add(dept);
                return a;
            }

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

            @Override
            public String js(String s) {
                return null;
            }

        };
    }
}

 添加注解

package com.coco.springcloud.service;

import com.coco.springcloud.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 org.springframework.web.bind.annotation.PostMapping;

import java.util.List;

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

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

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

    @PostMapping("/dept/add")
    boolean addDept(Dept dept);

    @GetMapping("/dept/json")
    String js(String s);
}

8.HystrixDashboard-流监控

pom文件

<?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>springcloud</artifactId>
        <groupId>com.coco</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-consumer-dashboard</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.coco</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>0.0.1-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>
<!--Eureka-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
<!--Ribbon-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
<!--Hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
<!--Dashboard-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
    </dependencies>

</project>

 application.yml

server:
  port: 9001
hystrix:
  dashboard:
    proxy-stream-allow-list: "*"

编写启动类,启动并访问:http://localhost:9001/hystrix

package com.coco.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@EnableHystrixDashboard
public class DeptConsumerDashboard_9001 {
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumerDashboard_9001.class, args);
    }
}

服务提供者

编写流监控Servlet,开启熔断机制,并在控制类中具备熔断操作

package com.coco.springcloud;

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableEurekaClient //添加后服务启动时自动注册进Eureka中
@EnableDiscoveryClient//向controller中注册discovery获取配置信息
@EnableHystrix//开启熔断
public class DeptProvider_8002 {
    public static void main(String[] args) {
        SpringApplication.run(DeptProvider_8002.class, args);
    }


    @Bean
    public ServletRegistrationBean hystrixMetricsStreamServlet() {
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new HystrixMetricsStreamServlet());
        registrationBean.addUrlMappings("/actuator/hystrix.stream");
        return registrationBean;
    }
}
package com.coco.springcloud.controller;

import com.coco.springcloud.pojo.Dept;
import com.coco.springcloud.service.DeptService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Controller;
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;

@RestController
public class DeptController {
    @Autowired
    private DeptService deptService;

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

    @HystrixCommand(fallbackMethod = "hystrixGet")
    @GetMapping("/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
        Dept dept = deptService.queryById(id);
        System.out.println(dept);

        if (dept == null) {
            throw new RuntimeException("id=>" + id + ", 不存在该用户");
        }
        return dept;
    }

    //抛出异常后执行备选方案
    public Dept hystrixGet(@PathVariable("id") Long id) {
        return new Dept().setDeptno(id).setDname("id=>" + id + ", 不存在该用户").setDb_source("FROM 8002");
    }

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

9.Zuul-路由网关,统一外部请求访问的地址

 pom文件

<?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>springcloud</artifactId>
        <groupId>com.coco</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-zuui-9527</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!--拿到实体类-->
        <dependency>
            <groupId>com.coco</groupId>
            <artifactId>springcloud-api</artifactId>
            <version>0.0.1-SNAPSHOT</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.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.2.10.RELEASE</version>
        </dependency>
    </dependencies>
</project>

application.yml

server:
  port: 9527
spring:
  application:
    name: springcloud-zuul-gateway

eureka:
  client:
    service-url:
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
  instance:
    instance-id: spri-zuul-9527
    prefer-ip-address: true


info:
  app.name: Zuul网关
  company.name: FROM 9527

management:
  endpoints:
    web:
      exposure:
        include: "*"
  info:
    env:
      enabled: true
zuul:
  routes:
    mydept.serverId: springcloud-provider-TiGongZhe
    mydept.path: /mydept/**

编写启动类,启动并访问:http://www.star.com:9527/springcloud-provider-tigongzhe/dept/list

package com.coco.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@EnableZuulProxy
public class ZuulApplication_9527 {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication_9527.class, args);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值