SpringCloud_Feign和Zuul

在之前我们进行远程服务调用是使用的Spring提供的RestTemplate进行调用,虽然也完成了功能,但是写法是非常不优雅的,还需要进行拼接字符串来进行参数传递。为了解决这个问题,引入SrpingCloud的组件Feign。

Feign简介:

Feign可以把Rest请求进行伪装,伪装成类似于SpringMVC的Controller一样。你不用再自己去拼接url、拼接参数等操作,一切都交给Feign去做。

Feign是Netflix开发的声明式、模板化的HTTP客户端,Feign可以帮助我们更加便捷、优雅的调用HTTP API。

在SpringCloud中,使用Feign非常简单:创建一个接口,并且在接口上添加一些注解,代码就完成了。

SpringCloud对Feign进行了增强,使Feign支持了SpringMVC的注解,并整合了Ribbon、Eureka和Hystrix,从而让Feign的使用更加方便。

改良入门程序,使用Feign进行远程调用:

1、添加Feign的启动器:

		<!--引入Feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

2、在引导类上添加注解启用Feign:
在这里插入图片描述
3、创建UserClient接口,使用UserClient接口进行远程连接:

package com.xsh.consumer.client;

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

@FeignClient("SERVICE-PRODUCER")
public interface UserClient {

    @RequestMapping("user/findByid/{uid}")
    public User findByid(@PathVariable Integer uid);
}

@FeignClient注解:注解的参数是你需要远程连接的服务名
接口内的方法是你需要远程连接的服务提供方的方法,方法必须保持一直,并且访问路径也要一致。

4、在服务消费方使用UserClient进行远程调用:

package com.xsh.consumer.controller;

import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.xsh.consumer.client.UserClient;
import com.xsh.consumer.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.stereotype.Controller;
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;

@RestController
@RequestMapping("/consumer/user")
public class UserController {

    @Autowired
    private UserClient userClient;

    @RequestMapping("/{uid}")
    @HystrixCommand
    public String findByid(@PathVariable Integer uid){
        return userClient.findByid(uid).toString();
    }

}

直接注入UserClient,然后使用其中的接口方法即可实现远程连接。

使用Feign开启Hystrix熔断器:

Feign默认情况下是集成了Hystrix的,但是是不开启的,所以我们首先要在配置文件中覆盖默认配置来开启Hystrix。

1、开启Hystrix:

feign:
  hystrix:
    enabled: true   #开启Hystrix

2、创建UserClient的实现类,编写熔断方法

package com.xsh.consumer.client;

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

@Component
public class UserClientImpl implements UserClient {
    @Override
    public User findByid(Integer uid) {
        User user=new User();
        user.setUname("服务器正忙!");
        return user;
    }
}

实现类实现UserClient接口方法,实现方法就是熔断方法,返回提示信息,然后该实现类要使用注解交由Spring容器来管理。

3、将实现类通过@FeignClient注解的参数绑定打Hystrix中:

package com.xsh.consumer.client;

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

@FeignClient(value = "SERVICE-PRODUCER",fallback = UserClientImpl.class)
public interface UserClient {

    @RequestMapping("user/findByid/{uid}")
    public User findByid(@PathVariable Integer uid);
}

至此,就可以实现使用Feign开启Hystrix进行熔断。

服务网关Zuul简介:

服务网关是微服务架构中一个不可或缺的部分。通过服务网关统一向外提供Rest API的过程中,除了具备服务器路由、负载均衡功能之外,它还具备了权限控制等功能。

SpringCloud中的Zuul就担任了这样一个角色,为微服务架构提供前门保护的作用,同时将权限控制这些较重的非业务逻辑内容迁移到服务路由层面,是的服务集群主体能够具备更高的可复用性和可测试性。

Zuul是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用。
Zuul核心是一系列的过滤器,这些过滤器可以完成以下功能:

  • 身份认证与安全:识别每个资源的验证请求,并拒绝那些与要求不符的请求。
  • 审查与监控:在边缘位置追踪有意义的数据和统计结果,从而带来精确的生产视图。
  • 动态路由:动态的将请求路由到不同的后端集群。
  • 压力测试:逐渐增加指向集群的流量,以了解性能。
  • 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求。
  • 静态响应处理:在边缘位置直接建立部分响应,从而避免转发到内部集群。
  • 多区域弹性

加入Zuul网关之后的微服务架构:
在这里插入图片描述
不管是来自客户端的请求,还是内部服务调用,一切服务的请求都会经过Zuul这个网关,然后再由网关来实现鉴权、动态路由等等操作,Zuul就是我们服务的唯一入口。

入门案例:通过Zuul网关路由到服务提供方

1、创建module
在这里插入图片描述
2、修改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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.xsh</groupId>
    <artifactId>service-zuul</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!--定义SpringCloud的版本号-->
    <properties>
        <spring-cloud.version>Finchley.SR2</spring-cloud.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
    </dependencies>

    <!--统一管理SpringCloud版本号-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

3、覆盖默认配置

server:
  port: 10010
spring:
  application:
    name: service-zuul

4、在引导类上添加注解启用Zuul

package com.xsh.zuul;

import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

@SpringCloudApplication
@EnableZuulProxy  //启用Zuul网管组件
public class ZuulApplication {
    public static void main(String[] args) {
        SpringApplication.run(ZuulApplication.class,args);
    }
}

5、配置路由转发到服务提供方

zuul:
  routes:
    service-producer:  #路由名称,自定义,一般以服务名称
      path: /service-producer/**
      url: http://localhost:8081

配置完成之后通过http://localhost:10010/service-producer/user/findByid/1该路径就可以访问到服务提供方的接口。
我们是通过配置的路由访问Zuul网关,然后由网关转发到服务提供方接口的。

Zuul网关的四种路由配置方式:

在入门案例中,使用的是第一种配置方式,通过自定义的名称转发到固定服务提供方的接口。

**第二种配置方式:**引入Eureka,通过服务id拉取服务列表进行转发,并且可以进行负载均衡

zuul:
  routes:
    service-producer:  #路由名称,自定义,一般以服务名称
      path: /service-producer/**
      #url: http://localhost:8081
      serviceId: SERVICE-PRODUCER
eureka:
  client:
    service-url:
      defaultZone: http://localhost:10086/eureka

这种配置方式是通过Eureka拉取服务列表来进行转发的,所以还需要在Zuul的module中引入Eureka。

**第三种配置方式:**相当于第二种配置方式的简化

zuul:
  routes:
    service-producer: /service-producer/** #路由名称,自定义,一般以服务名称
      #path: /service-producer/**
      #url: http://localhost:8081
      #serviceId: SERVICE-PRODUCER

第四种配置方式: 其实也可以不配,Zuul默认会通过服务id进行拉取转发,不过通常还是采用第三种方式进行简单的灵活设置。

路由前缀配置:

zuul:
  routes:
    service-producer: /service-producer
  prefix: /api

通过zuul.perfix属性可以配置路由的前缀,配置了路由前缀之后,访问路由必须加上对应的前缀才可以访问。

Zuul过滤器:

Zuul作为网关的其中一个重要功能,就是实现请求的鉴权,而这个动作我们通常是通过Zuul提供的过滤器来实现的。

1、IZuulFilter接口和ZuulFilter实现类

IZuulFilter是Zuul网关过滤器的最顶层接口,ZuulFiter是IZuulFilter的抽象实现类。

ZuulFilter的具体方法说明:

public abstract ZuulFilter implements IZuulFilter{
	abstract public String filterType();
	abstract public int filterOrder();
	boolean shouldFilter();  //继承自IZuulFilter
	Object run() throws ZuulException;  //继承自IZuulFilter
}

shouldFilter():方法返回一个布尔值,判断该过滤器的逻辑代码是否需要执行,返回true则执行,false则不执行。

run():过滤器的业务逻辑代码。

filterType():返回字符串,代表过滤器的类型。包含如下四种:

  • pre:请求在被路由之前执行;
  • route:在请求被路由时执行;
  • post:在route和error过滤器之后执行;
  • error:处理请求发生错误时执行。

filterOrder():通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。

2、过滤器执行生命周期
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值