java微服务之springcloud快速入门day02feign(代码片段)

蓝盒子bluebox 蓝盒子bluebox     2022-12-07     495

关键词:

Java 微服务之 SpringCloud快速入门day02 (二)Feign

一、Feign

在前面的学习中,我们使用了Ribbon的负载均衡功能,大大简化了远程调用时的代码:

String baseUrl = "http: / /user-service/user / " ;
User user = this.restTemplate.getFor0bject(baseUrl + id,User.class)

如果就学到这里,你可能以后需要编写类似的大量重复代码,格式基本相同,无非参数不一样。

有没有更优雅的方式,来对这些代码再次优化呢?

这就是我们接下来要学的Feign的功能了。

1、简介

为什么叫伪装?

Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样。

你不用再自己拼接url,拼接参数等等操作,—切都交给Feign去做。

项目主页:https://github.com/OpenFeign/feign

2、实现

(1)引入依赖

在这里插入图片描述

  <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.0.1.RELEASE</version>
  </dependency>
(2)添加注解

在这里插入图片描述

@EnableFeignClients
(3)创建UserClient接口:Feign客户端

在这里插入图片描述
在这里插入图片描述
根据服务名拿到了对应的ip地址和端口

package com.itzheng.consumer.client;

import com.itzheng.consumer.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient("user-service")
public interface UserClient 

    @GetMapping("user/id")
    User queryBuId(@PathVariable("id") Long id);



表示去user-service这个服务提供方去获取对应的值以及设置对应的参数(即封装远程调用)

(4)完善ConsumerController

在这里插入图片描述

package com.itzheng.consumer.web;

import com.itzheng.consumer.client.UserClient;
import com.itzheng.consumer.pojo.User;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("consumer")
@DefaultProperties(defaultFallback = "defaultFallback")
public class ConsumerController 
    //@Autowired
   // private RestTemplate restTemplate;
  /*
    @Autowired
    private DiscoveryClient discoveryClient;
*/
    @Autowired
    private UserClient userClient;

    @GetMapping("/id")
    public User queryById(@PathVariable("id") Long id) 

        return userClient.queryBuId(id);

    

    @GetMapping("/id")
    //@HystrixCommand(fallbackMethod = "queryByIdFallback") //开启线程隔离和服务降级(HystrixCommand失败服务的指令)
/*    @HystrixCommand(commandProperties = 
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
    )
    */
    //fallbackMethod失败的时候调用的方法,成功 时候默认调用下面的方法
    @HystrixCommand(
         commandProperties = 
                 //设置请求的次数为10次当请求请求失败超过5次的时候打开熔断
               @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
                 //短路多久以后开始尝试是否恢复,默认5s  这里设置为10s
               @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),
                 //出错百分比阈值,当达到此阈值后,开始短路。默认60%
               @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60")
         
    )
/*
    public String queryById(@PathVariable("id") Long id) 
        if(id % 2 == 0)
            throw new RuntimeException("");
        

        String url = "http://user-service/user/" + id;
        String user = restTemplate.getForObject(url, String.class);
        return user;
    
 */
    //fallbackMethod失败的时候调用的方法,与成功时候调用的方法的名称可以不一样,但是返回值和参数必须相同
    public String queryByIdFallback(Long id) 
        return "不好意思,服务器态拥挤了";
    
    public String defaultFallback() 
        return "不好意思,服务器态拥挤了";
    


/*

    @GetMapping("/id")
    public User queryById(@PathVariable("id") Long id) 
        //根据服务id获取实例
        //List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
        //从实例当中取出IP和端口
        //ServiceInstance instance = instances.get(0);
        //随机,论询、hash
        //ServiceInstance instance = client.choose("user-service");
        //String url = "http://"+ instance.getHost()+":"+instance.getPort()+"/user/"+id;
        //System.out.println(url);
        //底层还是上述的代码,内部通过拦截器将请求拦截下来,
        //获取到user-service自动去负载均衡后获取ip地址将user-service替换
        String url = "http://user-service/user/" + id;
        User user = restTemplate.getForObject(url, User.class);
        return user;
    
*/



(5)完善ConsumerApplication:开启Feign功能

在这里插入图片描述

package com.itzheng;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
//@EnableCircuitBreaker
//@EnableDiscoveryClient
//@SpringBootApplication
@EnableFeignClients
@SpringCloudApplication
public class ConsumerApplication 
   /* @Bean
    @LoadBalanced
    public RestTemplate restTemplate()
        return new RestTemplate();
    */
    public static void main(String[] args) 
        SpringApplication.run(ConsumerApplication.class,args);
    

(6)删除这两个依赖,因为在Feign当中已经有了该依赖

在这里插入图片描述
全部依赖

<?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>cloud-demo</artifactId>
        <groupId>com.itzheng.demo</groupId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consumer-demo</artifactId>

    <dependencies>

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>


    </dependencies>

</project>
(7)开启Feign熔断机制

去掉之前的注解
在这里插入图片描述
设置Feign当中熔断的超时时长,开启熔断功能
在这里插入图片描述

ribbom:
  ConnectionTimeOut: 500  #如果500毫秒没有获取的请求异常就抛出异常
  ReadTimeOut: 2000 #如果超过2000秒没有获取到请求返回的值就抛出异常
feign:
  hystrix:
    enabled: true  #开启熔断功能

完善UserClient

创建UserClientImpl实现类

在这里插入图片描述

package com.itzheng.consumer.client;

import com.itzheng.consumer.pojo.User;
import org.springframework.stereotype.Component;

@Component
public class UserClientImpl implements UserClient 
    @Override
    public User queryBuId(Long id) 

        return null;
    


完善UserClient类
在这里插入图片描述

package com.itzheng.consumer.client;

import com.itzheng.consumer.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient(value = "user-service" ,fallback = UserClientImpl.class)
public interface UserClient 

    @GetMapping("user/id")
    User queryBuId(@PathVariable("id") Long id);



完善UserClientImpl实现类

在这里插入图片描述

package com.itzheng.consumer.client;
import com.itzheng.consumer.pojo.User;
import org.springframework.stereotype.Component;

@Component
public class UserClientImpl implements UserClient 
    @Override
    public User queryBuId(Long id) 
        User user = new User();
        user.setName("未知用户!");
        return user;
    

(8) 重新运行项目

在这里插入图片描述
http://localhost:8088/consumer/8

在这里插入图片描述
停止user-service
在这里插入图片描述
再次访问
在这里插入图片描述

(9)请求压缩在这里插入图片描述
(10)日志级别

在这里插入图片描述

java微服务之springcloud快速入门day01初始springcloud(代码片段)

一、SpringCloud的简介微服务是一种架构方式,最终肯定需要技术架构去实施。微服务的实现方式很多,但是最火的莫过于SpringCloud了。为什么?后台硬:作为Spring家族的一员,有整个Spring全家桶靠山,背景十分强大。... 查看详情

java微服务之springcloud快速入门day01eureka注册中心快速入门(代码片段)

一、Eureka注册中心简介1、认识Eureka首先我们来解决第一问题,服务的管理。问题分析在刚才的案例中,user-service对外提供服务,需要对外暴露自己的地址。而consumer(调用者)需要记录服务提供者的地址。将来地址出现... 查看详情

java微服务之springcloud快速入门day02zuul网关,面向服务的路由,zuul过滤器(代码片段)

Java微服务之SpringCloud快速入门day02(三)Zuul网关一、简介1、相关概念官网:https://github.com/Netflix/zuulZuul:维基百科:电影《捉鬼敢死队》中的怪兽,Zuul,在纽约引发了巨大强乱。事实上,在微服务架构中࿰... 查看详情

java微服务之springcloud快速入门day02zuul网关,面向服务的路由,zuul过滤器(代码片段)

Java微服务之SpringCloud快速入门day02(三)Zuul网关一、简介1、相关概念官网:https://github.com/Netflix/zuulZuul:维基百科:电影《捉鬼敢死队》中的怪兽,Zuul,在纽约引发了巨大强乱。事实上,在微服务架构中࿰... 查看详情

java微服务之springcloud快速入门day02hystrix线程隔离,服务降级(代码片段)

Hystrix1、简介Hystrix,英文意思是豪猪,全身都是刺,看起来就不好惹,是一种保护机制。Hystrix也是Netflix公司的一款组件。主页:https://github.com/Netflix/Hystrix那么Hystrix的作用是什么呢?具体要保护什么呢ÿ... 查看详情

java微服务之springcloud快速入门day02hystrix线程隔离,服务降级(代码片段)

Hystrix1、简介Hystrix,英文意思是豪猪,全身都是刺,看起来就不好惹,是一种保护机制。Hystrix也是Netflix公司的一款组件。主页:https://github.com/Netflix/Hystrix那么Hystrix的作用是什么呢?具体要保护什么呢ÿ... 查看详情

java微服务之springcloud快速入门day01系统架构的演变,服务调用方式(代码片段)

一、系统架构的演变1、集中式架构当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是影响项目开发的关键。存在的问题&... 查看详情

java微服务之springcloud快速入门day01eureka注册中心高级部分(集群)(高可用)(代码片段)

接下来我们详细讲解Eureka的原理及配置。1、基础框架Eureka架构中的三个核心角色:服务注册中心Eureka的服务端应用,提供服务注册和发现功能,就是刚刚我们建立的eureka-server服务提供者提供服务的应用,可以是SpringBoo... 查看详情

java微服务之springcloud快速入门day01eureka注册中心高级部分(集群)(高可用)(代码片段)

接下来我们详细讲解Eureka的原理及配置。1、基础框架Eureka架构中的三个核心角色:服务注册中心Eureka的服务端应用,提供服务注册和发现功能,就是刚刚我们建立的eureka-server服务提供者提供服务的应用,可以是SpringBoo... 查看详情

springcloud微服务开发快速入门(代码片段)

...变6.微服务开发框架7.微服务需要学习什么?小结二、SpringCloud1.SpringCloud介绍2.SpringBoot与SpringCloud的区别3.服务拆分和远程调用实现远程调用案例案例需求注册RestTemplate实现远程 查看详情

springcloud微服务开发快速入门(代码片段)

...变6.微服务开发框架7.微服务需要学习什么?小结二、SpringCloud1.SpringCloud介绍2.SpringBoot与SpringCloud的区别3.服务拆分和远程调用实现远程调用案例案例需求注册RestTemplate实现远程 查看详情

java之springcloud微服务搭建(第一个阶段)springboot项目实现商品服务器端是调用(代码片段)

Java之SpringCloud微服务入门到精通Spring微服务快速入门(Eureka)一、Springcloud微服务概述1、微服务中的相关概念(1)服务注册与发现(2)负载均衡(3)熔断(4)链路追踪(5)API网关2... 查看详情

springcloud系列教程汇总整理手册

...系列之集成Dubbo的方式    >>sourcedownload2、微服务之SpringCloud2.1服务治理实现SpringCloud系列使用NetflixEureka进行服务治理2.2声明式服务调用SpringCloud系列之声明式服务调用NetflixFeign2.3客户端负载均衡SpringCloud系列之客户端负载均... 查看详情

springcloud微服务快速教程之gateway服务网关

...,是异步非阻塞网关,ZUUL2也是异步非阻塞的,但未纳入springcloud整合计划  基于WebFlux ,与spring-boot-starter-web冲突,要排除该依赖;ZUUL1是阻塞io的APIGateway;  性能上,自然是异步非阻塞的gateway胜出,不过实际项目中,... 查看详情

springcloud之zuul网关入门

SpringCloud实现微服务的架构基本成型:  使用SpringCloudNetflix中的Eureka实现了服务注册中心以及服务注册与发现;而服务间通过Ribbon或Feign实现服务的消费以及均衡负载。  为了使得服务集群更为健壮,使用Hystrix的融断机制来... 查看详情

springcloud实战微服务之——微服务简介以及入门使用(代码片段)

微服务概述微服务是什么?微服务解决了什么问题?微服务有什么特点?单体架构是什么?一个归档包包含了应用所有功能的应用程序,我们通常称之为单体应用。架构单体应用的架构风格,我们称之为单... 查看详情

springcloud从入门到进阶——使用springboot搭建微服务

内容  SpringBoot整合SpringCloud的Eureka、Zuul等组件,快速实现简单易懂且具有服务熔断、负载均衡的分布式架构1.0,体验微服务的魅力。版本  IDE:IDEA2017.2.2x64  JDK:1.8.0_171  manve:3.3.3  SpringBoot:1.5.9.RELEASE  SpringCloud... 查看详情

springcloud微服务之跨服务调用后端接口

SpringCloud微服务系列博客:SpringCloud微服务之快速搭建EurekaServer:https://blog.csdn.net/egg1996911/article/details/78787540SpringCloud微服务之注册服务至EurekaServer:https://blog.csdn.net/egg1996911/article/details/78859200Sp 查看详情