Feign是一个声明式的Web服务客户端,可帮助我们更加便捷、优雅地调用HTTP API

Feign可以与Eureka和Ribbon组合使用以支持负载均衡

一、构建Eureka Server

【基于第二章节创建的Eureka Server】

二、构建Eureka Client提供者集群项目

【基于第三章节构建的Eureka Client提供者集群项目】

1:提供者集群项目中创建controller

mhb-cloud-producer mhb-cloud-producer-extend

【创建UserVo对象】com\applesnt\vo\UserVo.java

package com.applesnt.vo;
import lombok.Data; @Data
public class UserVo { private String user_id; private String user_name; private String code; public UserVo(String user_id, String user_name, String code) {
this.user_id = user_id;
this.user_name = user_name;
this.code = code;
} public UserVo() {
}
}

mhb-cloud-producer :9904

mhb-cloud-producer-extend:9905

【创建Controller】com\applesnt\controller\FeignProducerController.java

package com.applesnt.controller;

import com.applesnt.vo.UserVo;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List; @RestController
@RequestMapping("/producer")
public class FeignProducerController { /*返回传递过来的id
* 请求路径:http://localhost:9904/producer/get/123
* */
@GetMapping("/get/{id}")
public String getId(@PathVariable("id") String id){
System.out.println("-----"+id);
return "我是提供者 端口是9904 传递的参数= "+id;
} /*参数为id 返回user对象
* 请求路径:http://localhost:9904/producer/getuserbyid/123
* */
@GetMapping("/getuserbyid/{id}")
public UserVo getUserById(@PathVariable("id") String id){
UserVo userVo = new UserVo();
userVo.setUser_id(id);
userVo.setUser_name("applesnt");
userVo.setCode("9904");
return userVo;
} /*
* 返回user对象
* 访问路径:http://localhost:9904/producer/getuser2?id=123&name=lisi
* */
@GetMapping("/getuser2")
public UserVo getUser2(@RequestParam("id") String id,
@RequestParam("name") String name){
UserVo userVo = new UserVo();
userVo.setUser_id(id);
userVo.setUser_name(name);
userVo.setCode("9904");
return userVo;
} /*
* 返回user对象
* 访问路径:http://localhost:9904/producer/getuser3?user_id=123&user_name=lisi
* */
@GetMapping("/getuser3")
public UserVo getUser3(UserVo userVo){
userVo.setUser_id(userVo.getUser_id());
userVo.setUser_name(userVo.getUser_name());
userVo.setCode("9904");
return userVo;
} /*参数uservo 返回UserVo
* postman body--raw(选择json格式)
* 数据格式:{"user_id":"123","user_name":"zhangsan"}
* */
@PostMapping("/getuser")
public UserVo getUser(@RequestBody UserVo userVo){
return userVo;
} /*返回UserVo集合
* 请求路径:http://localhost:9904/producer/getlist/
* */
@GetMapping("/getlist")
public List<UserVo> getUserList(){ List<UserVo> voList = new ArrayList<>();
UserVo userVo1 = new UserVo("1","zhangsan","9904");
UserVo userVo2 = new UserVo("2","lisi","9904");
UserVo userVo3 = new UserVo("3","wangwu","9904");
voList.add(userVo1);voList.add(userVo2);voList.add(userVo3); return voList;
}
}

三、创建Eureka消费者项目(基于Feign)

mhb-cloud-consumer-Feign:【端口 8801】

1:pom文件

<!--eureka客户端环境支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency> <!--feign环境支持-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

2:application.yml文件

debug: false

spring:
application:
name: mhb-cloud-consumer-feign #每一个微服务必须有这个应用名称 server:
port: 8801 #端口 eureka:
instance:
appname: consumer-feign #eureka application的名称
prefer-ip-address: true #开启ip显示eureka的主机服务
#eureka仪表盘的Instances格式
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
client:
service-url:
defaultZone: http://admin:123456@eureka1.com:8762/eureka/,http://admin:123456@eureka2.com:8762/eureka/,http://admin:123456@eureka3.com:8763/eureka/
#从eureka服务器注册表中获取注册表信息的时间间隔,默认30s
registry-fetch-interval-seconds: 30
#客户端发送变化同步到eureka服务器的时间间隔 默认30s
instance-info-replication-interval-seconds: 30
#询问eureka服务url信息的变化的间隔时间 默认300s
eureka-service-url-poll-interval-seconds: 300
#最初同步到eureka服务器的时间 默认40s
initial-instance-info-replication-interval-seconds: 40
#注册表是否压缩
g-zip-content: true
#eureka等待超时时间 默认是5s
eureka-server-connect-timeout-seconds: 5
#eureka等待读取时间 默认是8s
eureka-server-read-timeout-seconds: 8
#eureka客户端允许的所有eureka服务器连接的总数 默认200
eureka-server-total-connections: 200

3:启动类中开启Feign支持

@@EnableEurekaClient

@EnableFeignClients

package com.applesnt;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate; @SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //开启feign支持
public class MhbCloudConsumerFeignApplication { public static void main(String[] args) {
SpringApplication.run(MhbCloudConsumerFeignApplication.class, args);
}
}

4:构建Feign远程调用接口

@FeignClient(name = "mhb-cloud-producer",configuration = FeignClientsConfiguration.class)

com\applesnt\service\FeignClientService.java

package com.applesnt.service;

import com.applesnt.vo.UserVo;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/*
name:提供者的服务名称
configuration:使用默认配置类 FeignClientsConfiguration
默认配置支持springmvc注解
*/
@FeignClient(name = "mhb-cloud-producer",configuration = FeignClientsConfiguration.class)
public interface FeignClientService { /*value要写全路径
* PathVariable一定要指定value值
* */
@GetMapping("/producer/get/{id}")
public String getId(@PathVariable("id") String id); @GetMapping("/producer/getuserbyid/{id}")
public UserVo getUserById(@PathVariable("id") String id); @GetMapping("/producer/getuser2")
public UserVo getUser2(@RequestParam("id") String id,
@RequestParam("name") String name); /*
* 如果传入复杂(vo类型)参数时 不支持get请求 远程调用对象必须要用post请求
* 所以getUser3是调用失败的
* */
@GetMapping("/producer/getuser3")
public UserVo getUser3(UserVo userVo); /*POST请求 如果是复杂对象 可以使用@RequestBody 也可以不使用*/
@PostMapping("/producer/getuser")
public UserVo getUser(@RequestBody UserVo userVo); @GetMapping("/producer/getlist")
public List<UserVo> getUserList();
}

5:构建远程调用controller

【构建UserVo对象】com\applesnt\vo\UserVo.java

package com.applesnt.vo;
import lombok.Data; @Data
public class UserVo { private String user_id; private String user_name; private String code; public UserVo(String user_id, String user_name, String code) {
this.user_id = user_id;
this.user_name = user_name;
this.code = code;
} public UserVo() {
}
}

【构建远程调用Controller】com\applesnt\controller\FeignConsumerController.java

package com.applesnt.controller;

import com.applesnt.service.FeignClientService;
import com.applesnt.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List; @RestController
@RequestMapping("/feign")
@Slf4j
public class FeignConsumerController { @Autowired/*feign远程服务接口注入*/
private FeignClientService feignClientservice; @GetMapping("/get/{id}")
//http://127.0.0.1:8801/feign/get/123
public String getId(@PathVariable("id") String id){ String reutrnStr = feignClientservice.getId(id);
log.info("feign调用 = {}",reutrnStr); return reutrnStr;
} @GetMapping("/getuserbyid/{id}")
//http://127.0.0.1:8801/feign/getuserbyid/123
public UserVo getUserById(@PathVariable("id") String id){ UserVo userVo = feignClientservice.getUserById("123");
log.info("feign调用 = {}",userVo); return userVo;
} @GetMapping("/getuser2")
//http://127.0.0.1:8801/feign/getuser2?id=123&name=zhangsan
public UserVo getUser2(@RequestParam(name = "id",required = false) String id,
@RequestParam("name") String name){ UserVo userVo = feignClientservice.getUser2(id,name);
log.info("feign调用 = {}",userVo); return userVo;
} @GetMapping("/getuser3")
//http://127.0.0.1:8801/feign/getuser3?user_id=123&user_name=zhangsan
public UserVo getUser3(UserVo userVo){ /*feign调用-会报错,不支持get远程调用*/
UserVo uVo = feignClientservice.getUser3(userVo);
log.info("feign调用 = {}",uVo); return uVo;
} @PostMapping("/getuser")
//http://127.0.0.1:8801/feign/getuser【要用postman模拟post请求】
public UserVo getUser(@RequestBody UserVo userVo){ UserVo uVo = feignClientservice.getUser(userVo);
log.info("feign调用 = {}",uVo); return uVo;
} @GetMapping("/getlist")
//http://127.0.0.1:8801/feign/getlist
public List<UserVo> getUserList(){ List<UserVo> list = feignClientservice.getUserList();
log.info("feign调用 = {}",list); return list;
}
}

6:Feign远程调用测试

分别启动Eureka服务集群、mhb-cloud-consumer-feign、mhb-cloud-producer、mhb-cloud-producer-extend六个服务

http://127.0.0.1:8801/feign/getuser2?id=123&name=zhangsan

第一次访问:

第二次访问:

四、Feign调用非微服务

创建远程调用service接口

@FeignClient(name = "xxxx",url = "http://localhost:8761")

com\applesnt\service\FeignClientService2.java

package com.applesnt.service;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.*; /*不写configuration属性 默认使用FeignClientsConfiguration
* 默认配置支持springmvc注解
* */
@FeignClient(name = "xxxx",url = "http://localhost:8761")
public interface FeignClientService2 { @GetMapping(value = "/eureka/apps")
public String getapp(); }

在FeignConsumerController中追加远程调用方法:


@Autowired/*feign远程服务接口注入(非微服务)*/
private FeignClientService2 feignClientService2; /*访问非微服务*/
//http://127.0.0.1:8801/feign/getapp
@GetMapping("/getapp")
public String getapp(){
String reutrnStr = feignClientService2.getapp();
return reutrnStr;
}

五、Feign日志配置

由于Feign默认不开启日志,所有我们要创建一个配置类用于覆盖默认配置

com\applesnt\config\FeignLogConfiguration.java

package com.applesnt.config;

import feign.Logger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; @Configuration
public class FeignLogConfiguration { @Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}

2:在feign的远程调用service接口中,配置上FeignLogConfiguration类

@FeignClient(name = "mhb-cloud-producer",configuration = FeignLogConfiguration.class)

3:在application.yml中开启service接口的日志输出

logging:
level:
com.applesnt.service.FeignClientService: debug

4:日志输出

SpringCloud(四)学习笔记之Feign的更多相关文章

  1. springcloud Eureka学习笔记

    最近在学习springcloud,抽空记录下学习笔记;主要记录Eureka的实现过程和高可用性的实现 Eureka是一个服务治理框架,它提供了Eureka Server和Eureka Client两个 ...

  2. SpringCloud Alibaba学习笔记

    目录 目录 目录 导学 为什么学 学习目标 进阶目标 思路 Spring Cloud Alibaba的重要组件 环境搭建 Spring Boot必知必会 Spring Boot特性 编写第一个Spri ...

  3. springcloud Ribbon学习笔记二

    之前介绍了如何搭建eureka服务并开发了一个用户服务成功注册到了eureka中,接下来介绍如何通过ribbon来从eureka中获取用户服务: springcloud ribbon提供客户端的负载均 ...

  4. SpringCloud(六)学习笔记之Zuul

    Zuul 在云平台上提供动态路由,监控,弹性,安全等边缘服务的框架.Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门 Hystrix+Ribbon(不使用Feign) ...

  5. SpringCloud(五)学习笔记之Hystrix

    在微服务架构中多层服务之间会相互调用,如果其中有一层服务故障了,可能会导致一层服务或者多层服务故障,从而导致整个系统故障.这种现象被称为服务雪崩效应. Hystrix组件就可以解决此类问题,Hystr ...

  6. springcloud Zuul学习笔记

    SpringCloud Zull是一个基于NetflixZuul实现的API网关组件,它实现了请求路由,负载均衡,校验过滤等功能;本文主要记录springcloud zuul的入门级demo开发过程; ...

  7. springcloud Ribbon学习笔记一

    上篇已经介绍了如何开发eureka服务并让多个服务进行相互注册,接下来记录如何开发一个服务然后注册到eureka中并能通过ribbon成功被调用 开发一个用户服务并注册到eureka中,用户服务负责访 ...

  8. spring cloud学习笔记三 Feign与Ribbon负载均衡的区别

    一.Feign的介绍 Feign一般比较书面的解释是:Feign是一个声明式的WebService客户端,使用Feign编写的WebService客户端更加简单,他的使用方法是定义一个接口,然后在上线 ...

  9. SpringCloud(三)学习笔记之Ribbon

    spring Cloud Ribbon 是一个客户端的负载均衡器,它提供对大量的HTTP和TCP客户端的访问控制. 客户端负载均衡即是当浏览器向后台发出请求的时候,客户端会向 Eureka Serve ...

随机推荐

  1. 多GPU使用详解

    目录: 介绍 记录设备状态 手动分配状态 允许GPU内存增长 在多GPU系统是使用单个GPU 使用多个 GPU 一.介绍 在一个典型的系统中,有多个计算设备.在 TensorFlow 中支持的设备类型 ...

  2. 【SQL SERVER】索引

    在做开发过程中经常会接触数据库索引,不只是DBA才需要知道索引知识,了解索引可以让我们写出更高质量代码. 索引概述 聚集索引 非聚集索引 唯一索引 筛选索引 非聚集索引包含列 索引概述 索引的存在主要 ...

  3. SpringBoot,SpringMvc, SpringCloud

    1,SpringBoot VS SpringMvc VS SpringBoot SpringBoot: SpringBoot 是一个快速开发的框架,能够快速的整合第三方框架,简化XML配置,全部采用注 ...

  4. 蓝桥杯 K好数(Java)

    越来越觉得自己菜,一道简单的动态规划写不出来,题解也是看了很多份才看懂了,所以尽量以图表的方式写了题解,希望我的题解能帮到其他人吧.(;´Д`) 首先是题目: 输入描述: 输入包含两个正整数,K和L. ...

  5. prometheus+grafana实现监控过程的整体流程

    prometheus安装较为简单,下面会省略安装步骤: 一.服务器启动 Prometheus启动 ./prometheus --config.file=prometheus.yml Grafana启动 ...

  6. python 介绍,环境配置

    python介绍 介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,Guido开始写能够解释Python语言语法的解释器.Python这个名字,来 ...

  7. Java并发基础06. 线程范围内共享数据

    假设现在有个公共的变量 data,有不同的线程都可以去操作它,如果在不同的线程对 data 操作完成后再去取这个 data,那么肯定会出现线程间的数据混乱问题,因为 A 线程在取 data 数据前可能 ...

  8. IIS 组成

    HTTP.sys      http.sys 侦听来自网络的 HTTP 请求,将它们传递到 IIS 并返回响应. 它是一种可以从命令行停止和启动的服务.      "NET STOP HTT ...

  9. iOS, Xcode11,项目提示第三方库报错无法运行 bundle format unrecognized, invalid, or unsuitable

    检查你有没有把静态库和动态库配置错误!! 下图处是配置动态库的地方! 对于动态库和静态库都有使用的时候,注意把静态库设置成“Do not Embeded”

  10. Navicat安装教程

    Navicat安装教程 1.下载: 链接:https://pan.baidu.com/s/1uLlstPYrsjaNhZqVu9aFfQ 提取码:393r 2.下载完成之后如图所示: 首先安装第二个, ...