什么是SpringCloud

微服务架构
• "微服务”一词源于 Martin Fowler的名为 Microservices的博文,可以在他的官方博客上找到
http://martinfowler.com/articles/microservices.html
• 微服务是系统架构上的一种设计风格,它的主旨是将一个原本独立的系统拆分成多个小型服务,这些小型服务都在各自独立的进程中运行,服务之间一般通过 HTTP 的 RESTfuLAPI 进行通信协作。
• 被拆分成的每一个小型服务都围绕着系统中的某一项或些耦合度较高的业务功能进行构建,并且每个服务都维护着白身的数据存储、业务开发自动化测试案例以及独立部署机制。
• 由于有了轻量级的通信协作基础,所以这些微服务可以使用不同的语言来编写。

定义:是一些列组件的集合
组件:

  • 注册中心
  • 配置中心
  • 熔断器
  • 网关
  • 负载均衡
  • 消息总线
  • 数据监控

SpringCloud与Dubbo的区别

  • Dubbo是基于RPC协议实现远程调用的,同时要求所用语言必须是Java
  • SpringCloud规定服务之间通过http协议进行通信
  • Dubbo性能较好(因为底层基于socket),SpringCloud功能全

SpringCloud 服务治理(详细解释在代码注释中)

服务注册与发现

Eureka

• Eureka 是 Netflix 公司开源的一个服务注册与发现的组件 。
• Eureka 和其他 Netflix 公司的服务组件(例如负载均衡、熔断器、网关等) 一起,被 Spring Cloud 社区整合为
Spring-Cloud-Netflix 模块。
• Eureka 包含两个组件:Eureka Server (注册中心) 和 Eureka Client (服务提供者、服务消费者)。

Eureka – 搭建服务

搭建eureka服务,编写provider服务提供者,编写consumer服务消费者端,并将服务注册到eureka注册中心,使用Ribbon实现负载均衡

这些简单的实体类与返回的结果集就不粘贴出来了,主要看eureka搭建后的效果

父pom.xml
pom文件中包含一些nacos,OpenFeign后面会用

<?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"><modelVersion>4.0.0</modelVersion><groupId>com.fs</groupId><artifactId>study-springcloud</artifactId><version>1.0-SNAPSHOT</version><modules><module>fs-provider-8001</module><module>fs-consumer-80</module><module>fs-server-eureka-7001</module><module>fs-api-commons</module><module>fs-server-eureka-7002</module><module>fs-server-eureka-7003</module><module>fs-provider-nacos-8001</module><module>fs-consumer-nacos-80</module><module>fs-provider-8002</module><module>fs-consumer-openFeign-80</module></modules><!--    作为父工程--><packaging>pom</packaging><dependencyManagement><dependencies><!--      spring boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.3.2.RELEASE</version><type>pom</type>
<!--        import        导入父工程的配置--><scope>import</scope></dependency><!--      spring cloud --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Hoxton.SR6</version><type>pom</type>
<!--        import        导入父工程的配置--><scope>import</scope></dependency><!--   spring-cloud-alibaba-dependencies  2.2.1.RELEASE --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2.2.1.RELEASE</version><type>pom</type><scope>import</scope></dependency><!--    eureka-server    --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId><version>2.2.4.RELEASE</version></dependency><!--    eureka-client    --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><version>2.2.4.RELEASE</version></dependency><!--            整合MyBatis--><!--    mysql  --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.20</version><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.20</version></dependency><!--     MyBatisPlus   --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.3.2</version></dependency>
<!--            lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency></dependencies></dependencyManagement><dependencies></dependencies></project>

搭建 Provider 和 Consumer 服务。

Provider 创建 fs-provider-8001 项目

多个提供复制一下,然后更改端口号与application.yml中配置注册的注册中心即可
我只粘贴出application.yml,pom.xml,主启动,与服务提供的controller,因为dao,service就是使用了MyBatis-plus

pom.xml

<?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>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-provider-8001</artifactId><dependencies><!--     spring-boot-starter-web  spring-boot-starter-actuator绑定在一块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--        eureka-Client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><!--
第一种是:如果你的应用不会再需要返回xml的系列化格式,那么直接在pom.xml文件中将jackson-dataformat-xml这外包排除即可(如果其他包也进行了jackson-dataformat-xml的依赖引用也要视情况排除):第二种是:不排除jackson-dataformat-xml包,而是直接在相应接口方法或Controller上明确指定将返回JSON格式的值:@GetMapping(value = "/user-instance", produces = MediaType.APPLICATION_PROBLEM_JSON_VALUE)
-->
<!--            排除controller返回的格式为xml--><exclusions><exclusion><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId></exclusion></exclusions></dependency><!--        mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency>
<!--        jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>
<!--        druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency>
<!--        MyBatis-puls--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--        自己的实体类--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies>
</project>

application.yml

搭建集群provider集群就把 server.prot改下,吧defaultZone:多个地址用逗号隔开
注意的是,域名记得在host文件中修改域名与端口的映射

server:port: 8001
spring:application:name: fs-providerdatasource:username: rootpassword: rooturl: jdbc:mysql://192.168.93.132:3306/fs_springclouddriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource #自定义数据源# 配置eureka
eureka:instance:hostname: localhost # 主机名,写的是域名,本机在host文件中映射prefer-ip-address: true # 将当前实例的ip注册到eureka server中.默认是false 注册主机名ip-address: 127.0.0.1 # 修改instance-id显示
#    # 修改instance-id显示,在eureka中的显示名称
#    instance-id: ${eureka.instance.ip-address}:${spring.application.name}:${server.port}
#    lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server发送心跳的时间间隔
#    lease-expiration-duration-in-seconds: 90 # 如果90秒内eureka server没有收到eureka client的心跳包,则剔除该服务client:register-with-eureka: true # 将提供注册到注册eureka中心fetch-registry: true # 从eureka上抓取已有的注册信息service-url:defaultZone: http://localhost:7001/eureka #,http://localhost2:7002/eureka,http://localhost3:7003/eureka # 注册中心地址# 配置MyBatis-plus日志
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

FsProvider8001主启动

package com.fs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;@SpringBootApplication
//开启Eureka客户端
@EnableEurekaClient
public class FsProvider8001 {public static void main(String[] args) {SpringApplication.run(FsProvider8001.class,args);}
}

PaymentController

package com.fs.controller;import com.fs.pojo.Payment;
import com.fs.result.Result;
import com.fs.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;
import java.util.concurrent.TimeUnit;@RestController
@RequestMapping("/payment")
public class PaymentController {//注入业务层@Autowiredprivate PaymentService paymentService;@RequestMapping("/findAll")public Result<List<Payment>> findAll(){List<Payment> all = paymentService.findAll();return new Result<List<Payment>>(true,"查询成功8001",all);}@RequestMapping("/testTimeOut")public Result test(){try {//让方法停止2秒,模拟方法执行时间过长,因为Ribbon的超时时间默认为1秒,超时就会报错TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return new Result<List<Payment>>(true,"查询成功");}}

Consumer 创建 fs-consumer-80 消费者 使用 RestTemplate 完成远程调用。

Resttemplate

• Spring提供的一种简单便捷的模板类,用于在 java 代码里访问 restful 服务。
• 其功能与 HttpClient 类似,但是 RestTemplate 实现更优雅,使用更方便。

pom.xml

<?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>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-consumer-80</artifactId><dependencies><!--     spring-boot-starter-web  spring-boot-starter-actuator绑定在一块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--        eureka-Client--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId><!--            排除controller返回的格式为xml--><exclusions><exclusion><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId></exclusion></exclusions></dependency><!--        自己的实体类--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

application.yml

server:port: 80spring:application:name: fs-consumer-80
eureka:client:register-with-eureka: false # 消费者我目前的用途不需要将消费者注册到注册中心fetch-registry: true # 从注册中心拉取服务registry-fetch-interval-seconds: 30 # 默认30秒定时去注册中心拉取服务service-url:defaultZone: http://localhost:7001/eureka #,http://localhost2:7002/eureka,http://localhost3:7003/eureka # 注册中心地址# 配置的方式设置Ribbon的负载均衡
#FS-PROVIDER: # 设置的我们服务提供方的应用名称
#  ribbon: # 固定写法
#    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  #负载均衡的规则,表示加权规则,yml配置优先级第一,Java代码第二,默认的最后# 自定义属性来存储注册中心 提供者的名字
provider:name: FS-PROVIDER

主启动 FsConsumer80

package com.fs;import com.fs.config.MyRule;
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.ribbon.RibbonClient;@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient //激活发现客户端
//开启客户端负载均衡,不使用默认的轮询,
//name 设置我们这个负载均衡用于那个服务提供方  configuration 使用我们自定义的配置类中配置的负载均衡
@RibbonClient(name = "FS-PROVIDER",configuration = MyRule.class)
public class FsConsumer80 {public static void main(String[] args) {SpringApplication.run(FsConsumer80.class,args);}
}

MyRule 定义负载均衡策略

== Ribbon负载均衡器==

  • 定义:解决客户端的服务负载均衡算法处理器

  • 功能:

    • 负载均衡
    • 简化远程调用过程
  • 使用:

    • 开启负载均衡功能(默认轮询策略)

      @LoadBanlance
      
    • 修改主机名为服务名

      http://服务名称/login
      
  • 怎么修改负载均衡策略

    • 注解方式

      ### xxx 是一个JavaConfig类,其中㤇配置使用的策略Bean
      @RibbonClient(name="",configuration = XXX.Class)
      
    • 配置方式

      [服务名称1]:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
      [服务名称2]:ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.BestAvailableRule
      
MyRule
package com.fs.config;import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*
编码的方式设置
定义Ribbon负载均衡的配置类注意:这个类不能在@Configuration 下的@@ComponentScan扫描的包下因为@SpringBootApplication这个注解定义为扫描被这个注解注解的类的包及其子包所以,我们这个Ribbon负载均衡的配置类就只能从新新建一个包,不在主配置类包下及其子包就可以了这里配置为随机后记得在主启动类上加上一个注解@RibbonClient*/
@Configuration
public class MyRule {@Beanpublic IRule myIRule(){//import com.netflix.loadbalancer.RandomRule;这个类就就代表负载均衡为随机//创建负载均衡的策略为随机RandomRule randomRule = new RandomRule();return randomRule;}
}

RestTemplateConfig 注入RestTemplate

package com.fs.config;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;/*
定义restTemplate*/
@Configuration
public class RestTemplateConfig {@Bean//客户端负载均衡@LoadBalanced //使用默认的负载均衡轮询public RestTemplate restTemplate(){return new RestTemplate();}
}

PaymentController 服务消费者

package com.fs.controller;import com.fs.pojo.Payment;
import com.fs.result.Result;
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.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;import java.util.List;@RestController
@RequestMapping("/consumer")
public class PaymentController {//注入RestTemplate@Autowiredprivate RestTemplate restTemplate;//注入DiscoveryClient,动态从eureka server 中获取 provider 的host与ip@Autowiredprivate DiscoveryClient discoveryClient;//    String host;
//    int port;//    private String PAYMENT_URL ="http://"+host+ ":"+port;//从application.yml文件中读取@Value("${provider.name}")private String providerName;@RequestMapping("/payment/findAll")public Result<List<Payment>> findAll(){//搭建集群后,使用服务名称做url,负载均衡的调用注册中心的服务Result<List<Payment>> result = restTemplate.getForObject("http://"+providerName+"/payment/findAll", Result.class);return result;}//    @RequestMapping("/payment/findAll")
//    public Result<List<Payment>> findAll(){//        //得到服务的实体,为什么是集合呢?因为未来的一个微服务名称是搭建集群的
//        List<ServiceInstance> instances = discoveryClient.getInstances("FS-PROVIDER");
//        String host = null;
//        int port = 0;
//
//        if (instances.size()>0){//            //获取第一个
//            ServiceInstance serviceInstance = instances.get(0);
//            //见名知意
//            host = serviceInstance.getHost();
//            port = serviceInstance.getPort();
//        }else {//            return null;
//        }
//        Result<List<Payment>> result = restTemplate.getForObject("http://"+host+":"+port+"/payment/findAll", Result.class);
//        result.setMessage(host+":"+port);
//        return result;
//    }
}

搭建 Eureka Server 服务。

pom.xml

<?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>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-server-eureka-7001</artifactId><dependencies><!--    eureka-server    --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency><!--     spring-boot-starter-web  spring-boot-starter-actuator绑定在一块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies></project>

application.yml

server:port: 7001
spring:application:name: fs-server-eureka-ha
eureka:instance:hostname: localhost #主机名,域名,本机在host文件配置client:register-with-eureka: false # 是否将自己注册到eureka,搭建继续需要将eurekaserver注册到注册中心,相互注册fetch-registry: false # 是否从EurekaServer抓取已有的注册信息service-url:defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka# eureka集群
#  client:
#    register-with-eureka: true # 是否将自己注册到eureka,搭建继续需要将eurekaserver注册到注册中心,相互注册
#    fetch-registry: true # 是否从EurekaServer抓取已有的注册信息
#    service-url:
#      defaultZone: http://localhost2:7002/eureka,http://localhost3:7003/eureka
#  server:
#    enable-self-preservation: false # 默认true 开启自我保护机制,但是开发中可以关掉,方便开发,实际生产一定使用默认的true
#    eviction-interval-timer-in-ms: 3000 #默认60秒

主启动 ServerEureka7001

package com.fs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;@SpringBootApplication
//开启eureka的服务
@EnableEurekaServer
public class ServerEureka7001 {public static void main(String[] args) {SpringApplication.run(ServerEureka7001.class,args);}
}

测试Eureka – 搭建服务

启动ServerEureka7001
启动FsProvider8001
启动FsConsumer80

浏览器分别打开:
http://localhost:7001/

http://localhost:8001/payment/findAll

http://localhost/consumer/payment/findAll
通过消费端使用RestTemplate远程调用我们的服务提供者

Eureka – 相关配置及特性

- instance

eureka:instance:hostname: localhost # 主机名client:service-url:defaultZone: http://localhost:8761/eureka # eureka服务端地址,将来客户端使用该地址和eureka进行通信register-with-eureka: true # 是否将自己的路径 注册到eureka上。eureka server 不需要的,eureka provider client 需要fetch-registry: true # 是否需要从eureka中抓取路径。eureka server 不需要的,eureka consumer client 需要

- server

eureka:server:#是否开启自我保护机制,默认trueenable-self-preservation:#清理间隔(单位毫秒,默认是60*1000)eviction-interval-timer-in-ms:instance:lease-renewal-interval-in-seconds: 30 # 每一次eureka client 向 eureka server发送心跳的时间间隔lease-expiration-duration-in-seconds: 90 # 如果90秒内eureka server没有收到eureka client的心跳包,则剔除该服务

- client

eureka:client:service-url:# eureka服务端地址,将来客户端使用该地址和eureka进行通信defaultZone:register-with-eureka: # 是否将自己的路径 注册到eureka上。fetch-registry: # 是否需要从eureka中抓取数据。

- dashboard

eureka:dashboard:enabled: true # 是否启用eureka web控制台path: / # 设置eureka web控制台默认访问路径

Consul客户端配置(了解,不常用)

  • 服务ip和地址
  • 服务名称
    换汤不换药,总的使用差不多
    • Consul 是由 HashiCorp 基于 Go 语言开发的,支持多数据中心,分布式高可用的服务发布和注册服务软件。
    • 用于实现分布式系统的服务发现与配置。
    • 使用起来也较 为简单。具有天然可移植性(支持Linux、windows和Mac OS X);安装包仅包含一个可执行文件,
    方便部署 。
    • 官网地址: https://www.consul.io
spring:cloud:consul:host: localhost # consul 服务端的 ipport: 8500 # consul 服务端的端口 默认8500discovery:service-name: ${spring.application.name} # 当前应用注册到consul的名称prefer-ip-address: true # 注册ipapplication:name: consul-provider # 应用名称

OpenFeign

什么是Feign

  • 定义:是微服务之间通过http协议调用的简化使用的框架

  • 事实:

    • Feign自动集成Ribbon,且默认开启相关功能
  • 使用:

    • 导包

      <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
      </dependency>
      
    • 配置
      这个配置信息可以在springboot的项目idea按两下shitf,输入feign**properties(****properties)这样的类中都可以发现这个类有哪些配置可以在yml配置文件中配置

      ribbon:ConnectTimeout: 1000 # 连接超时时间 默认1sReadTimeout: 3000 # 逻辑处理的超时时间 默认1s
      
    • 编码

      • 开启Feign功能

        @EnableFeignClients
        
      • 编写Feign接口

        //  指定当前类的方法都从Eureka中对应的服务去调用
        @FeignClient("服务的名称")
        public interface ProviderService {// 通过Controller的地址映射注解告诉Feign该类findOne2方法从服务提供者的/findOne/{id}地址获取信息// 通过Controller的参数获取注解告诉Feign的参数信息// 通过返回值告诉Feign应该返回的参数应该封装的格式@GetMapping("/goods/findOne/{id}")public Goods findOne(@PathVariable("id") int id);}
        

SpringBoot开启DEBUG日志

  • 开启SpringBoot框架的DEBUG日志

    • 开启全部

      # 设置当前的日志级别 debug,feign只支持记录debug级别的日志
      logging:level:root: debug
      
    • 开启部分

      logging:level:com.fs: debug
      
  • 开启Feign的日志

    • 必须开启对应Feign接口包的日志为DEBUG

    • 编码

      • 定义日志级别

        @Configuration
        public class FeignLogConfig {/*NONE,不记录BASIC,记录基本的请求行,响应状态码数据HEADERS,记录基本的请求行,响应状态码数据,记录响应头信息FULL;记录完成的请求 响应数据*/@Beanpublic Logger.Level level(){return Logger.Level.FULL;}
        }
      • 配置生效

        @FeignClient(value = "FEIGN-PROVIDER",configuration = FeignLogConfig.class)
        

Nacos客户端配置 基于OpenFeign远程调用(代码中详细注释)

• Nacos(Dynamic Naming and Configuration Service) 是阿里巴巴2018年7月开源的项目。
• 它专注于服务发现和配置管理领域 致力于帮助您发现、配置和管理微服务。Nacos 支持几乎所有主流类型的“服务”的发现、配置和管理。
• 一句话概括就是Nacos = Spring Cloud注册中心 + Spring Cloud配置中心。
• 官网:https://nacos.io/
• 下载地址: https://github.com/alibaba/nacos/releases

docker安装nacos

#1.3.2
# 创建 /home/dockerdata/nacos/logs目录用于挂载# 拉取nacos镜像
docker pull nacos/nacos-server:1.3.2
# 运行容器 这里面的sql语句需要在github的nacos中去拷贝执行  执行成功后访问ip:端口/nacos
docker run -d \
-e PREFER_HOST_MODE=ip \
-e MODE=standalone \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_SERVICE_HOST=47.112.174.148 \
-e MYSQL_SERVICE_PORT=3306 \
-e MYSQL_SERVICE_USER=root \
-e MYSQL_SERVICE_PASSWORD=root \
-e MYSQL_SERVICE_DB_NAME=nacos \
-e TIME_ZONE='Asia/Shanghai' \
-v /docker/dockerdata/nacos/logs:/home/nacos/logs \
-p 8848:8848 \
--name nacos1.3.2 \
--restart=always \
nacos/nacos-server:1.3.2# 意思
docker run -d \
-e PREFER_HOST_MODE=hostname \
-e MODE=standalone \
-e SPRING_DATASOURCE_PLATFORM=mysql \
-e MYSQL_MASTER_SERVICE_HOST=数据库ip \
-e MYSQL_MASTER_SERVICE_PORT=数据库端口 \
-e MYSQL_MASTER_SERVICE_USER=用户名 \
-e MYSQL_MASTER_SERVICE_PASSWORD=密码 \
-e MYSQL_MASTER_SERVICE_DB_NAME=对应的数据库名 \
-e MYSQL_SLAVE_SERVICE_HOST=从数据库ip \
-p 8848:8848 \
--name nacos-sa-mysql \
--restart=always \
nacos/nacos-server

使用上面的父项目搭建

fs-provider-nacos-8001 服务提供端

pom.xml

<?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>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-provider-nacos-8001</artifactId><dependencies><!--        springcloud alibaba nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--这两个spring-cloud-starter-alibaba-nacos-discovery都可以--><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery -->
<!--        <dependency>-->
<!--            <groupId>org.springframework.cloud</groupId>-->
<!--            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->
<!--            <version>0.9.0.RELEASE</version>-->
<!--        </dependency>--><!-- https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client --><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>1.3.2</version></dependency><!--     spring-boot-starter-web  spring-boot-starter-actuator绑定在一块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--        mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--        jdbc--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><!--        druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId></dependency><!--        MyBatis-puls--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--        自己的实体类--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

application.yml

server:port: 8001
spring:application:name: fs-provider-nacosdatasource:username: rootpassword: rooturl: jdbc:mysql://192.168.93.132:3306/fs_springclouddriver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource #自定义数据源# 将服务提供者注册到nacos注册中心cloud:nacos:discovery:server-addr:  192.168.93.132:8848 # 配置nacos 服务端地址# 配置MyBatis-plus日志
mybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

主启动 FsNacosProvider8001

package com.fs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class FsNacosProvider8001 {public static void main(String[] args) {SpringApplication.run(FsNacosProvider8001.class,args);}
}

PaymentController 服务提供controller

package com.fs.controller;import com.fs.pojo.Payment;
import com.fs.result.Result;
import com.fs.service.PaymentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;
import java.util.concurrent.TimeUnit;@RestController
@RequestMapping("/payment")
public class PaymentController {//注入业务层@Autowiredprivate PaymentService paymentService;@RequestMapping("/findAll")public Result<List<Payment>> findAll(){List<Payment> all = paymentService.findAll();return new Result<List<Payment>>(true,"查询成功nacos8001",all);}@RequestMapping("/testTimeOut")public Result test(){try {//让方法停止2秒,模拟方法执行时间过长,因为Ribbon的超时时间默认为1秒,超时就会报错TimeUnit.SECONDS.sleep(2);} catch (InterruptedException e) {e.printStackTrace();}return new Result<List<Payment>>(true,"查询成功");}
}

fs-consumer-nacos-80 服务消费端

pom.xml

<?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>study-springcloud</artifactId><groupId>com.fs</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>fs-consumer-nacos-80</artifactId><dependencies><!--        springcloud alibaba nacos--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--这两个spring-cloud-starter-alibaba-nacos-discovery都可以--><!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-alibaba-nacos-discovery --><!--        <dependency>--><!--            <groupId>org.springframework.cloud</groupId>--><!--            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>--><!--            <version>0.9.0.RELEASE</version>--><!--        </dependency>--><!-- https://mvnrepository.com/artifact/com.alibaba.nacos/nacos-client --><dependency><groupId>com.alibaba.nacos</groupId><artifactId>nacos-client</artifactId><version>1.3.2</version></dependency><!--        openFeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--     spring-boot-starter-web  spring-boot-starter-actuator绑定在一块 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--        自己的实体类--><dependency><groupId>com.fs</groupId><artifactId>fs-api-commons</artifactId><version>1.0-SNAPSHOT</version></dependency></dependencies></project>

application.yml

server:port: 80spring:application:name: fs-consumer-nacoscloud:nacos:discovery:server-addr:  192.168.93.132:8848 # 配置nacos 服务端地址logging:level:#    root: debug # 开启springboot的debug的日志信息,不配置springboot默认是info#    com.fs: debug # 开启部分springboot的debug的日志信息# feign日志以什么级别监控那个feign组件功能使用的接口,使用debug级别(只能记录debug级别),然后调用服务方法,在控制台就能看到详细debug信息com.fs.springcloud.server.PaymentOpenFeignService: debug

主启动 FsNacosConsumer80

package com.fs;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;@SpringBootApplication
//开启OpenFeign
@EnableFeignClients
public class FsNacosConsumer80 {public static void main(String[] args) {SpringApplication.run(FsNacosConsumer80.class,args);}
}

OpenFeignConfig

package com.fs.config;import feign.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*
OpenFeign的日志配置类*/
@Configuration
public class OpenFeignConfig {@BeanLogger.Level feignLoggerLevel(){//表示开启的是详细的feign日志,FULL表示最为详细的,点进去有4个return Logger.Level.FULL;}//还需要在yml中配置feign日志已什么级别监控那个接口
}

PaymentOpenFeign 为OpenFeign的接口

package com.fs.feign;import com.fs.config.OpenFeignConfig;
import com.fs.pojo.Payment;
import com.fs.result.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;import java.util.List;
/*** feign的声明式接口,发起远程调用的,简化restTemplate** 1.定义接口* 2.接口上添加注解@FeignClient(value = "注册中心服务提供者名",configuration=定义的OpenFeign的日志类)* 3.编写调用接口,接口的声明规则和提供方接口保持一致* 4.去controller注入改接口对象,调用接口方法来完成远程调用*/
@FeignClient(value = "fs-provider-nacos",configuration = OpenFeignConfig.class)
public interface PaymentOpenFeign {//复制服务提供的controller方法,路径记得加上controller类上的路径@RequestMapping("/payment/findAll")Result<List<Payment>> findAll();//测试time超时,由于我们在服务提供方的这个方法制作了sleep2秒,由于feign底层基于Ribbon,//Ribbon默认超时时间为1秒,所以报错java.net.SocketTimeoutException: Read timed out//解决办法在配置文件中配置Ribbon的超时时间@RequestMapping("/payment/testTimeOut")Result test();
}

PaymentController 使用OpenFeign远程调用服务提供者

package com.fs.controller;import com.fs.feign.PaymentOpenFeign;
import com.fs.pojo.Payment;
import com.fs.result.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/consumer")
public class PaymentController {//注入OpenFeign接口@Autowiredprivate PaymentOpenFeign paymentOpenFeign;@RequestMapping("/payment/findAll")public Result<List<Payment>> findAll(){//调用OpenFeign接口Result<List<Payment>> all = paymentOpenFeign.findAll();return all;}//测试time超时@RequestMapping("/payment/testTimeOut")Result test(){Result test = paymentOpenFeign.test();return test;}}

测试nacos

首先确保docker的nacos正常运行且能正常访问

运行:
FsNacosProvider8001
运行:
FsNacosConsumer80

浏览器访问nacos查看服务是否注册

直接访问服务提供接口,与使用消费者端远程调用服务提供接口

SpringCloud微服务架构,Spring Cloud 服务治理(Eureka,Consul,Nacos),Ribbon 客户端负载均衡,RestTemplate与OpenFeign实现远程调用相关推荐

  1. 全网最全微服务架构—Spring Cloud详解,没有比这更详细的了!

    原文地址: https://blog.51cto.com/14570694/2482244 本文不是讲解如何使用Spring Cloud的教程,而是探讨Spring Cloud是什么,以及它诞生的背景 ...

  2. 微服务架构Spring Cloud和Dubbo 还有EDAS

    现在 分布式项目 不用dubbo 都不好意思开口说架构. 出去面试 分布式服务必谈dubbo: 近几年来了 Spring Cloud; 然后最近 发现 阿里云推出了 EDAS,为你的dubbo服务安个 ...

  3. 微服务架构spring cloud - 分布式配置中心config(七)

    1.什么是spring-cloud-config 用来为分布式系统中的基础设施和微服务应用提供集体化的外部配置支持,它分为服务端和客户端.服务端也就是config服务,客户端就是其他的微服务. spr ...

  4. Spring Cloud源码分析——Ribbon客户端负载均衡

    年前聊了Eureka和Zookeeper的区别,然后微服务架构系列就鸽了三个多月,一直沉迷逛B站,无法自拔.最近公司复工,工作状态慢慢恢复(又是元气满满地划水).本文从以下3个方面进行分析(参考了翟永 ...

  5. 微服务架构spring cloud - gateway网关限流

    1.算法 在高并发的应用中,限流是一个绕不开的话题.限流可以保障我们的 API 服务对所有用户的可用性,也可以防止网络攻击. 一般开发高并发系统常见的限流有:限制总并发数(比如数据库连接池.线程池). ...

  6. 客户端负载均衡与服务端负载均衡对比

    客户端 服务端 开发团队灵活修改 运维人员把控修改 运维成本低,开发人员直接可以修改 运维成本高 强依赖注册中心 不依赖注册中心 微服务框架 tomcat等传统应用 服务端负载均衡 负载均衡是我们处理 ...

  7. 客户端负载均衡与服务端负载均衡

    原文:https://segmentfault.com/a/1190000011081111 通过Nginx负载均衡服务器发送到不同的上游服务器去处理,这种负载均衡就是一种典型的服务端负载均衡,那么客 ...

  8. 微服务等于Spring Cloud?一文告诉你微服务到底是什么

    作者:TIM XU 原文:https://xiaoxubeii.github.io/articles/microservices-architecture-introduction/ 1 微服务初探 ...

  9. Spring Cloud和常用组件Consul+Fegin+zuul总结

    一.微服务设计原则 单一职责原则 服务自治原则:服务是实体,它们独立地配置.更新和管理 轻量级通信原则 接口明确原则:每个服务的对外接口应该明确定义,并尽量保持不变. 参考网站https://blog ...

最新文章

  1. 网友们票选的2018 Best Paper,你pick谁?
  2. js面向对象程序设置——创建对象
  3. 一次性动态绑定多个droplistdown
  4. mysql Communications link failure druid
  5. Android 之父裁员 30%:开发者如何避免“被离职”?
  6. LVS+keepalived高可用负载均衡集群部署(一) ----数据库的读写分离
  7. sqlalchemy like
  8. Spring MVC 接收POST表单请求,获取参数总结
  9. windows下mongodb安装与使用
  10. 什么是VIE:Variable Interest Entities
  11. Win10输入法移除未知区域设置(qad-Latn) 美式键盘
  12. pycharm跳出括号快捷键
  13. MMD以及核公式推导
  14. 一次线上紧急事故的处理复盘
  15. HighNewTech:展望未来之十大颠覆技术
  16. 《视频解密》中文版(第四版)第十章 H.261和H.263(第二部分)
  17. 全向轮移动平台运动模型
  18. 医院信息系统基本功能规范(4)
  19. 解决不良贷款清收难 创新新对策
  20. (完全小白 ) 利用python实现QQ空间说说秒赞(改BUG)

热门文章

  1. 关于数据契约(DataContract)待续
  2. MySQL之架构与历史(二)
  3. 第三百一十九节,Django框架,文件上传
  4. js window.onlload 自遐想
  5. CentOS7 虚拟机搭建、初始设置、简单使用
  6. shell讲解-小案例
  7. struts2中访问servlet API
  8. KR C 传统C语言的函数定义
  9. WinForm实现窗体最小化后小图标在右边任务栏下
  10. Linux集群服务 LVS