谷粒学院——第十九章、数据同步_网关

news2024/11/15 5:56:16

Canal 数据同步(了解)

网关

image.png

API 网关介绍

API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能 需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题:
(1)客户端会多次请求不同的微服务,增加了客户端的复杂性。
(2)存在跨域请求,在一定场景下处理相对复杂。
(3)认证复杂,每个服务都需要独立认证。
(4)难以重构,随着项目的迭代,可能需要重新划分微服务。例如,可能将多个服务合并成一个或者将 一个服务拆分成多个。如果客户端直接与微服务通信,那么重构将会很难实施。
(5)某些微服务可能使用了防火墙 / 浏览器不友好的协议,直接访问会有一定的困难。
以上这些问题可以借助 API 网关解决。API 网关是介于客户端和服务器端之间的中间层,所有的外部请 求都会先经过 API 网关这一层。也就是说,API 的实现方面更多的考虑业务逻辑,而安全、性能、监控 可以交由 API 网关来做,这样既提高业务灵活性又不缺安全性。

Spring Cloud Gateway

Spring cloud gateway是spring官方基于Spring 5.0、Spring Boot2.0和Project Reactor等技术开发的 网关,Spring Cloud Gateway旨在为微服务架构提供简单、有效和统一的API路由管理方式,Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,其不仅提供统一的路由 方式,并且还基于Filer链的方式提供了网关基本的功能,例如:安全、监控/埋点、限流等。
image.png
网关提供API全托管服务,丰富的API管理功能,辅助企业管理大规模的API,以降低管理成本和安全风 险,包括协议适配、协议转发、安全策略、防刷、流量、监控日志等贡呢。一般来说网关对外暴露 的URL或者接口信息,我们统称为路由信息。如果研发过网关中间件或者使用过Zuul的人,会知道网关的 核心是Filter以及Filter Chain(Filter责任链)。Sprig Cloud Gateway也具有路由和Filter的概念。 下面介绍一下Spring Cloud Gateway中几个重要的概念。
(1)路由。路由是网关最基础的部分,路由信息有一个ID、一个目的URL、一组断言和一组Filter组 成。如果断言路由为真,则说明请求的URL和配置匹配
(2)断言。Java8中的断言函数。Spring Cloud Gateway中的断言函数输入类型是Spring5.0框架中 的ServerWebExchange。Spring Cloud Gateway中的断言函数允许开发者去定义匹配来自于http request中的任何信息,比如请求头和参数等。
(3)过滤器。一个标准的Spring webFilter。Spring cloud gateway中的filter分为两种类型 的Filter,分别是Gateway Filter和Global Filter。过滤器Filter将会对请求和响应进行修改处理
image.png
如上图所示,Spring cloud Gateway发出请求。然后再由Gateway Handler Mapping中找到与请求相匹配 的路由,将其发送到Gateway web handler。Handler再通过指定的过滤器链将请求发送到我们实际的服 务执行业务逻辑,然后返回。

创建模块(网关服务)

image.png
之后删除src文件,然后设置pom打包方式

引入依赖

<dependencies>
  <dependency>
    <groupId>org.jyunkai</groupId>
    <artifactId>common_utils</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
  </dependency>
  <!--gson-->
  <dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
  </dependency>
  <!--服务调用-->
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
  </dependency>
</dependencies>

启动类

@SpringBootApplication
@EnableDiscoveryClient
public class ApiGatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiGatewayApplication.class, args);
    }
}

配置文件

# 服务端口
server.port=8222
# 服务名
spring.application.name=service-gateway
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#开启从注册中心动态创建路由的功能,利用微服务名进行路由
spring.cloud.gateway.discovery.locator.enabled=true

#设置路由id
spring.cloud.gateway.routes[0].id=service-acl
#设置路由的uri   lb://nacos注册服务名称
spring.cloud.gateway.routes[0].uri=lb://service-acl
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[0].predicates=Path=/*/acl/**

#配置service-edu服务
spring.cloud.gateway.routes[1].id=service-edu
spring.cloud.gateway.routes[1].uri=lb://service-edu
spring.cloud.gateway.routes[1].predicates=Path=/eduservice/**

#配置service-edu服务
spring.cloud.gateway.routes[2].id=service-msm
spring.cloud.gateway.routes[2].uri=lb://service-msm
spring.cloud.gateway.routes[2].predicates=Path=/edumsm/**

基本配置

直接复制资料里面的三个包

config

⚠️注意:配置下面这个类以后,所有的 controller 上面不能再加 **@CrossOrigin** 注解
前端端口号也要从 9001 改为 8222!

/**
 * 处理跨域问题
 */
@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);

        return new CorsWebFilter(source);
    }
}

image.png

filter

/**
 * 全局Filter,统一处理会员登录与外部不允许访问的服务
 */
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {

    private AntPathMatcher antPathMatcher = new AntPathMatcher();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getURI().getPath();
        //谷粒学院api接口,校验用户必须登录
        if(antPathMatcher.match("/api/**/auth/**", path)) {
            List<String> tokenList = request.getHeaders().get("token");
            if(null == tokenList) {
                ServerHttpResponse response = exchange.getResponse();
                return out(response);
            } else {
//                Boolean isCheck = JwtUtils.checkToken(tokenList.get(0));
//                if(!isCheck) {
                    ServerHttpResponse response = exchange.getResponse();
                    return out(response);
//                }
            }
        }
        //内部服务接口,不允许外部访问
        if(antPathMatcher.match("/**/inner/**", path)) {
            ServerHttpResponse response = exchange.getResponse();
            return out(response);
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }

    private Mono<Void> out(ServerHttpResponse response) {
        JsonObject message = new JsonObject();
        message.addProperty("success", false);
        message.addProperty("code", 28004);
        message.addProperty("data", "鉴权失败");
        byte[] bits = message.toString().getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bits);
        //response.setStatusCode(HttpStatus.UNAUTHORIZED);
        //指定编码,否则在浏览器中会中文乱码
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }
}

handler

ErrorHandlerConfig

/**
 * 覆盖默认的异常处理
 */
@Configuration
@EnableConfigurationProperties({ServerProperties.class, ResourceProperties.class})
public class ErrorHandlerConfig {

    private final ServerProperties serverProperties;

    private final ApplicationContext applicationContext;

    private final ResourceProperties resourceProperties;

    private final List<ViewResolver> viewResolvers;

    private final ServerCodecConfigurer serverCodecConfigurer;

    public ErrorHandlerConfig(ServerProperties serverProperties,
                                     ResourceProperties resourceProperties,
                                     ObjectProvider<List<ViewResolver>> viewResolversProvider,
                                        ServerCodecConfigurer serverCodecConfigurer,
                                     ApplicationContext applicationContext) {
        this.serverProperties = serverProperties;
        this.applicationContext = applicationContext;
        this.resourceProperties = resourceProperties;
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public ErrorWebExceptionHandler errorWebExceptionHandler(ErrorAttributes errorAttributes) {
        JsonExceptionHandler exceptionHandler = new JsonExceptionHandler(
                errorAttributes,
                this.resourceProperties,
                this.serverProperties.getError(),
                this.applicationContext);
        exceptionHandler.setViewResolvers(this.viewResolvers);
        exceptionHandler.setMessageWriters(this.serverCodecConfigurer.getWriters());
        exceptionHandler.setMessageReaders(this.serverCodecConfigurer.getReaders());
        return exceptionHandler;
    }
}

JsonExceptionHandler

/**
 * 自定义异常处理
 */
public class JsonExceptionHandler extends DefaultErrorWebExceptionHandler {

    public JsonExceptionHandler(ErrorAttributes errorAttributes, ResourceProperties resourceProperties,
                                ErrorProperties errorProperties, ApplicationContext applicationContext) {
        super(errorAttributes, resourceProperties, errorProperties, applicationContext);
    }

    /**
     * 获取异常属性
     */
    @Override
    protected Map<String, Object> getErrorAttributes(ServerRequest request, boolean includeStackTrace) {
        Map<String, Object> map = new HashMap<>();
        map.put("success", false);
        map.put("code", 20005);
        map.put("message", "网关失败");
        map.put("data", null);
        return map;
    }

    /**
     * 指定响应处理方法为JSON处理的方法
     * @param errorAttributes
     */
    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
    }

    /**
     * 根据code获取对应的HttpStatus
     * @param errorAttributes
     */
    @Override
    protected int getHttpStatus(Map<String, Object> errorAttributes) {
        return 200;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/141637.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue+element对接第三方接口实现校园发帖网站“淘柳职”

一.前言 接上一篇博客《vueelementuijava 前后端分离实现学校帖子网站&#xff0c;仿照“淘柳职”学校大作业》 上一篇博客介绍的项目完全自带前、后端实现的&#xff0c;是一个完整的项目&#xff0c;现在作者在此基础上&#xff0c;利用已实现的前端&#xff0c;对接《淘柳职…

android12.0(S) DeviceOwner 应用默认授权(MDM 权限)

MDM(Mobile Device Manager) 通俗来讲就是管理设备使用 国内 MDM 服务商有 360 等 国外 MDM 服务商有 hexnode 等 当你在设备上配置了 DeviceOwner 后&#xff0c;状态栏下拉中会多出如下 关于 DeviceOwner 介绍可参考下面 Android DeviceOwner 应用的能力 Android Device…

品牌舆情监测系统简介,品牌舆情监测及应对方案?

品牌舆情监测是指通过观察和分析互联网和社交媒体上关于企业、产品或服务的信息&#xff0c;以了解消费者对企业、产品或服务的看法和感受。品牌舆情监测可以帮助企业了解消费者对企业、产品或服务的反馈&#xff0c;从而改进产品和服务&#xff0c;提高客户满意度。品牌舆情监…

【4.3】Ribbon饥饿加载

【4.3】Ribbon饥饿加载1 测试2 饥饿加载2.1 修改加载策略3 Ribbon负载均衡总结1 测试 重启Order服务&#xff0c;回到浏览器&#xff0c;打开浏览器的控制台&#xff0c;发起一次请求&#xff1a; 可以看到这次请求的耗时达到了390ms 再刷新一次&#xff1a; 可以看到这次时…

谷粒学院——第二十章、权限管理

一、权限管理需求描述 不同角色的用户登录后台管理系统拥有不同的菜单权限与功能权限&#xff0c;权限管理包含三个功能模块&#xff1a;菜单管理、角色管理和用户管理 1、菜单管理 &#xff08;1&#xff09;菜单列表&#xff1a;使用树形结构显示菜单列表 &#xff08;2&…

故障分析 | MySQL 主从延时值反复跳动

作者&#xff1a;徐文梁 爱可生DBA成员&#xff0c;负责客户项目的需求和维护。目前在数据库新手村打怪升级中。喜欢垂钓&#xff0c;如果你也喜欢垂钓&#xff0c;可以约个晴好天气&#xff0c;咱们一边钓鱼一边聊聊数据库&#xff0c;岂不快哉。 本文来源&#xff1a;原创投稿…

idea常用配置及问题解决

文章目录一、配置1.字体与行高2.快捷键(eclipse)3.Git配置4.添加Github账户5.设置字符集:UTF-86.设置自动编译7.顶部工具栏左侧显示8.配置.gitignore文件9.忽略、不显示文件10.显示包的层级结构(树结构)11.修改 Generate 快捷键12.设置代码提示忽略大小写13.去除pom.xml中依赖的…

【Go】入门Go语言

【Go】入门Go语言 前言 Go这门语言在当下已经越来越火热了&#xff0c;无论是后端开发岗&#xff0c;还是逆向安全岗位&#xff0c;亦或是渗透领域&#xff0c;乃至脚本小子…各个领域的人员都在分Go这一杯羹。 并且在最近越来越多的CTF比赛中&#xff0c;Go逆向、Go pwn&am…

idea配置maven步骤及常见问题

idea 配置maven步骤及常见问题maven 下载maven的配置配置系统环境变量maven本地仓库配置和镜像加速idea 中配置maven的设置常见问题&#xff0c;每次新建项目需要重新手动配置maven的解决maven 下载 首先&#xff0c;进入它的官网&#xff1a;链接: https://maven.apache.org/…

Find My资讯|被盗的AirPods通过苹果Find My找回并抓到盗窃者

美国一位盗窃案的受害者&#xff0c;他在圣安东尼奥莱昂谷的家中发现有人偷走了他的汽车后决定亲手将小偷捉住。打开Find My&#xff0c;他看到其中被拿走的AirPods显然是停在35号州际公路上的一个旅行站。在前往该站并发现一辆SUV里有五个人后&#xff0c;阿林顿打电话给警察寻…

谷粒学院——第二十二章、Jenkins可持续自动部署

一、安装内容 Jenkins&#xff08;本文主要安装&#xff09;、Maven、Git、JDK Jenkins与Github配合实现持续集成需要注意以下几点&#xff1a; ①Jenkins要部署到外网&#xff0c;因为内网Github是无法访问到的&#xff08;走过的坑&#xff01;&#xff09;&#xff0c;这里…

Usaco Training 刷怪旅 第三层 第六题:Ski Course Design

说实话&#xff0c;一开始看上一题的时候觉得太恶心就先来做这道&#xff0c;所以这题其实比上一题早做出来&#xff08;&#xff09; Farmer John has N hills on his farm (1 < N < 1,000), each with an integer elevation in the range 0 .. 100. In the winter, sin…

MVC MVVM架构

注&#xff1a;个人理解仅供参考1、MVC优点&#xff1a;1、模块独立&#xff0c;解耦缺点&#xff1a;1、厚重的ViewController2、遗失&#xff08;无处安放&#xff09;的网络逻辑3、较差的可测试性图2、MVVM优点1、低耦合&#xff1a;View可以独立于Model变化和修改&#xff…

【HybirdCLR】入门记录-Unity2021 + WebGL

目录前言环境案例学习先PC平台试一下转为WebGL平台动手做一个demo功能基本工作流程搭建环境构建项目补充致谢参考资料前言 之前一直有听说热更新技术&#xff0c;于是找点时间来研究一下热更新技术的使用。热更新的实现方式有很多种&#xff0c;这里笔者记录一下自己学习Hybir…

基于开源体系的云原生微服务治理实践与探索

作者&#xff1a;董艺荃&#xff5c;携程服务框架负责人 携程微服务产品的发展历程 携程微服务产品起步于 2013 年。最初&#xff0c;公司基于开源项目 ServiceStack 进行二次开发&#xff0c;推出 .Net 平台下的微服务框架 CServiceStack。 2014 年&#xff0c;公司推出 Jav…

【PhD Debate —11】矛与盾的对决——神经网络后门攻防

点击蓝字关注我们AI TIME欢迎每一位AI爱好者的加入&#xff01;2022年7月9日&#xff0c;AI TIME组织了Ph.D. Debate第十一期&#xff0c;题为“矛与盾的对决——神经网络后门攻防”的研讨活动&#xff0c;特别邀请了宾夕法尼亚州州立大学电子工程系博士生向臻、清华大学博士生…

区块链基础知识(一)

参考书籍《区块链原理、设计与应用》 基本原理 比特币网络工作流程 技术的演化与分类 分布式共识 交易性能 扩展性问题 数据库和存储系统 数据库也是区块链中重要的一环 分布式系统核心问题 单节点结构演变为分布式系统&#xff0c;首先遇到的问题就是一致性的保障。 一致性问…

小程序开发经验分享(5)-全屏展示小程序

小程序的 navigationBar,有APP开发经验的同学应该知道,navigationBar也就是程序最顶部的一条,我们同常的开发页面,也都是在navigationBar下方的主体区用标签开发UI部分 如下面两个图片,左边的翻译君官方小程序中上面就有这样一个navigationBar用于展示自己的title和菜单按…

K8s 认证工程师 CKA 考题分析和题库练习(下)

目录 10、考核知识&#xff1a;检查可用节点数量 题目内容 题目内容中文解释 做题解答 11、考核知识&#xff1a;一个 Pod 封装多个容器 题目内容 题目内容中文解释 官方文档搜索关键字&#xff1a;pod ​编辑做题解答 12、考核知识&#xff1a;持久卷 PersistentV…

Mac M1芯片 搭建RocketMQ

Mac M1芯片 搭建RocketMQ RocketMQ需要启动三个组件 1、nameserver 路由中心,为整个MQ集群提供服务协调与治理 2、broker 提供消息的转发和存储功能 3、console 控制台面板工具 1、下载RocketMQ https://rocketmq.apache.org/dowloading/releases/ 选择 Binary: rocketmq-all-4…