欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Cloud(6):Zuul的基本使用

程序员文章站 2022-08-11 13:56:02
网关:API Gateway 系统对外唯一入口,介于客户端和服务端之间,处理非业务功能 提供路由请求,鉴权,监控,缓存,限流等功能 简单理解:小区门卫,防止非法人员入内,居民也可以问路 实际理解:假设我部署完成一个电商网站,网关的作用如下 1.前端发起的请求都会发送到网关,比如URL是/api/us ......

网关:api gateway

系统对外唯一入口,介于客户端和服务端之间,处理非业务功能

提供路由请求,鉴权,监控,缓存,限流等功能

 

简单理解:小区门卫,防止非法人员入内,居民也可以问路

实际理解:假设我部署完成一个电商网站,网关的作用如下

1.前端发起的请求都会发送到网关,比如url是/api/user,网关判断后跳转到用户服务模块的服务器

2.双十一等时期高并发访问,网关可以做负载均衡,或者对访问进行限流降级

3.对权限进行限制,比如用户不能修改商品库存,于是网关限制用户访问商品编辑模块服务器

 

zuul不能凭空使用,至少要有服务模块以及eureka server

这里我就不重复写了,使用前文中提到的:

搭建eureka server和product-service:

使用feign搭建order-service:

 

新建zuul项目:

project->new project->spring initializr->命名为api-gateway

依赖eureka和zuul

Spring Cloud(6):Zuul的基本使用

 

然后是配置文件:前文都是yml格式的,感觉用不惯,还是继续用properties吧

主要是配置服务名称和eureka server地址

server.port=9000
spring.application.name=api-gateway
eureka.client.service-url.defaultzone=http://localhost:8761/eureka/

 

在启动类中加入注解:

package org.dreamtech.apigateway;

import org.springframework.boot.springapplication;
import org.springframework.boot.autoconfigure.springbootapplication;
import org.springframework.cloud.netflix.zuul.enablezuulproxy;

@springbootapplication
@enablezuulproxy
public class apigatewayapplication {

    public static void main(string[] args) {
        springapplication.run(apigatewayapplication.class, args);
    }

}

 

依次启动eureka server->product-service->order-service->api-gateway项目

eureka server:

Spring Cloud(6):Zuul的基本使用

注册成功

 

zuul的规则是:

zuul-host:zuul-port/service-name/**

我要访问的是order-service的/api/order/save路径

根据规则应该访问的是:

http://localhost:9000/order-service/api/order/save?user_id=1&product_id=1:

{"code":0,"data":{"id":0,"productname":"\"iphone1 data from port=8771\"","tradeno":"fe70c5d4-7467-43c6-902b-870bb8e763ed","price":1111,"createtime":"2019-05-18t03:16:32.165+0000","userid":1,"username":null}}

成功

 

或者访问:http://localhost:9000/product-service/api/product/find?id=1

{"id":1,"name":"iphone1 data from port=8771","price":1111,"store":10}

成功

 

一般情况下不会用/product-service和/order-service这种路径,于是想到自定义访问路径:

zuul.routes.order-service=/order/**

访问:http://localhost:9000/order/api/order/save?user_id=1&product_id=1即可

同时,原来的路径也没有失效

 

如果想让用户只能通过自定义路径访问,而不允许访问/product-service等路径

zuul.routes.order-service=/order/**
zuul.routes.product-service=/product/**
zuul.ignored-patterns=/*-service/**

 

如果不想开放某服务(不对某服务进行路由)

zuul.ignored-services=order-service

 

实际部署情况:各种服务通常在内网中,无法拿到ip,因此无法直接访问

用户通过公网ip只能访问到api-gateway,通过通过网关访问服务

就是下图这种方式

Spring Cloud(6):Zuul的基本使用

 

 

常见的问题解决:

1.多个服务的自定义路径不能设置成一样的

2.关于http请求头的信息的问题

实验

    @requestmapping("/save")
    @hystrixcommand(fallbackmethod = "saveorderfail")
    public object save(@requestparam("user_id") int userid, @requestparam("product_id") int productid, httpservletrequest request) {

        string token = request.getheader("token");
        string cookie = request.getheader("cookie");
        system.out.println(token+" : "+cookie);

        map<string, object> data = new hashmap<>();
        data.put("code", 0);
        data.put("data", productorderservice.save(userid, productid));
        return data;
    }

通过网关来访问order-service(postman工具):

Spring Cloud(6):Zuul的基本使用

打印情况:

hrvboenoiqnjvbwo : null

可以得出结论:获取cookie失败

原因:zuul过滤了请求头中的cookie信息

源码:

    private set<string> sensitiveheaders = new linkedhashset(arrays.aslist("cookie", "set-cookie", "authorization"));
    public void setsensitiveheaders(set<string> sensitiveheaders) {
        this.sensitiveheaders = sensitiveheaders;
    }

 

处理:

zuul.sensitive-headers=

 

注意:不要感觉奇怪,这里就是这么写,看源码set方法置空即可