简单BFF架构设计

        又到周五了有了一个小时的闲暇时间简单写点东西,介绍一个简单的BFF的架构。BFF:Backends For Frontends,其实现在是个比较常见的前端架构设计的方案,其最大的优势便在于前端可以高度自由的在Node层做一些server端才可以做的东西,比如SSR、登录态校验、对接服务端各微服务应用等。今天介绍一种简单的设计方案。

技术背景

        新建的系统需要对接集团的用户系统、权限系统以及多方业务的RPC服务端,业务属性原因Client端更新频率远高于Server端,且本地环境不可用(依赖服务的数据链路不通),只能依赖预发环境,预发环境与本地环境是隔离的(本地环境无法直接调用预发环境的RPC接口)。

架构图

技术设计

Demo代码

        首先由于需要主动调用多方RPC服务,便采用Node层作为聚合,对Client端提供http接口;因为Node端与Client端更新频率不同,为了提高部署效率,采用了两端分离的设计,分成了两个Project,Client端发布生成CDN资源,然后由Node端提供Controller层代码生成主文档模板,同时引入Client端CDN资源。类似代码如下:

import { Context } from 'egg';
import { Controller, Get, Provide, Priority, Inject } from '@midwayjs/decorator';@Provide()
@Priority(-1) // 降低匹配路由优先级,相当于router放在最后
@Controller('/')
export class HomeController {@Inject()ctx: Context;@Get('/*')async home() {const env =this.ctx.cookies?.get('x-env', { signed: false }) || this.ctx.aliEnv;this.ctx.logger.info(`env: ${env}`);// 远端持久化配置服务获取版本const {version} = await this.mockService.getConfig();const publicPath = {mockLocal: 'https://127.0.0.1:8000/',local: 'http://127.0.0.1:8000/',dev: `https://dev.g.alicdn.com/xxx/${version}/dist/`,pre: `https://dev.g.alicdn.com/xxx/${version}/dist/`,prod: `https://g.alicdn.com/xxx/${version}/dist/`,};return `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><link rel="stylesheet" href="${publicPath[env]}umi.css" /><script>window.routerBase = "/";</script><script>window.publicPath = window.resourceBaseUrl || "${publicPath[env]}";try {window.__CONFIG__ = {user: ${JSON.stringify(this.ctx.user)},env: '${this.ctx.aliEnv}',clientEnv: '${env}',};} catch (e) {console.error('=== 初始化数据失败(window.__CONFIG__) ===', e);}</script></head><body><div id="root"></div><script src="${publicPath[env]}umi.js"></script></body></html>`}
}

Client版本控制

        不同环境CDN路径不同,通过环境来区分配置,因为CDN资源不存在回归能力,所以将CDN资源发布时打上版本号路径,同时引入了第三方持久化配置服务,来配置不同环境的CDN版本号来实现Client资源的版本化控制部署。

本地开发代理&线上问题复现

        由于本地环境数据链路不通,因此日常开发调试都需要使用预发环境,为了方便开发,支持通过手动种植指定标识的cookie来mock对应环境来实现本地Client资源的引用,同时也可以用于排查线上Client问题。说到这里可能有很多人没注意,这里有一个隐藏技巧,那就是我们的系统往往预发或者生产访问地址协议时https的,而本地资源是http的,很多人第一反应就是 ,https的页面不能访问http的资源,但是其实是localhost和127.0.0.1除外 ,chrome认为localhost或者127.0.0.1是本机,是可以被信赖的

当然也可以通过本地配置类似代理的方式,将本地的http请求代理到预发环境,但是设计代理工具的配置、登录态token域名及跨域问题等,相对会繁琐一些也可以支持。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图腾柱PFC工作原理:一张图

视屏链接&#xff1a; PFC工作原理

SpringCloudFeign远程调用

文章目录 1. Feign 是什么2. Feign 的使用2.1 引入依赖2.2 写接口2.3 服务调用方2.4 启动测试 3. Feign 日志配置4. Feign 使用优化5. 注意包扫描问题6. 注意的问题6.1 参数问题6.2 Feign 自动装配 1. Feign 是什么 Feign 是一个声明式、模板化的 HTTP 客户端&#xff0c;它是…

【SQL】185. 部门工资前三高的所有员工(窗口函数dense_rank();区分rank()、row_number())

前述 推荐阅读&#xff1a;通俗易懂的学会&#xff1a;SQL窗口函数 题目描述 leetcode题目 185. 部门工资前三高的所有员工 思路 先按照departmentId分组&#xff0c;再按照salary排序 >窗口函数dense_rank() over() select B.name as Department,A.name as Employee,A…

Web题记

[CISCN 2019华北Day2]Web1 告诉我们想要的东西在flag表和flag字段&#xff0c;那应该是sql注入&#xff0c;先试试 试了一些发现会被检查到&#xff0c;随便传数字 除了1和2有返回结果&#xff0c;其余的都报错&#xff0c;应该是数字型注入&#xff0c;抓包看看过滤了哪些 这个…

Gradle模块化最佳实践

一&#xff0c;模块化的原因及意义 模块化是一种将大型的软件系统拆分成相互独立的模块的方法。具有以下优势&#xff1a; 代码复用&#xff1a;不同的模块可以共享相同的代码。这样可以避免重复编写相同的代码&#xff0c;提高开发效率。模块独立性&#xff1a;每个模块都可…

Elastic Stack--07--JavaAPI----文档(新增 、修改 、 查询 、 删除)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 JavaAPI-文档1.新增 Insert2.修改 Update3.查询 Get4.删除 Delete5.批量操作 BulkRequest批量新增批量删除 高级查询1.查询所有索引数据2.条件查询3.分页查询4.查询…

华容道问题求解_详细设计(五)之hash值和回放功能

&#xff08;续上文&#xff09; 布局的hash 值计算 笔者也参考了之前的一些文章&#xff0c;很多文章提到了怎么节省存贮空间来查找最优解&#xff0c;这不是笔者的目的。笔者的目的比较单一&#xff0c;就是找到最优解就行了。因此并没有在存贮上面进行过多的优化&#xff…

网络学习:数据的封装与解封装

目录 一、数据的封装与解封装 1. 数据的封装过程 2. 数据的解封装过程 二、数据的传输过程 1. 相关概念 2. 网络传输过程中数据封装和解封装模拟 一、数据的封装与解封装 1. 数据的封装过程 数据封装过程&#xff0c;在这里我们举例说明&#xff0c;以两台主机的通信为…

阿里云2核4G服务器支持人数并发测试,2核4G主机测评

阿里云2核4G服务器多少钱一年&#xff1f;2核4G配置1个月多少钱&#xff1f;2核4G服务器30元3个月、轻量应用服务器2核4G4M带宽165元一年、企业用户2核4G5M带宽199元一年。可以在阿里云CLUB中心查看 aliyun.club 当前最新2核4G服务器精准报价、优惠券和活动信息。 阿里云官方2…

记录西门子:IO隔离SCL编程

在PLC变量中创建IO输入输出 在PLC类型中创建输入和输出&#xff0c;并将PLC变量的输入输出名称复制过来 创建一个FC块或者FB块 创建一个DB块 MAIN主程序中&#xff1a;

C语言程序与设计——函数(二)递归练习

在上一篇文章中接触到了递归这种编程方法&#xff0c;下面我们将用几个程序加深以下对递归的理解。 递归实际上就是程序调用自身的编程技巧 递归程序的组成&#xff1a; 边界条件处理针对于问题的处理过程和递归过程结果返回 二分查找 首先分析二分查找的查找逻辑&#xff1a; …

深入理解操作系统Operator System(2)

目录 操作系统对上的管理 系统调用接口 用户操作接口&#xff08;库函数&#xff09; 系统调用和库函数的概念 结构层次示意图 总结 为什么要有操作系统❓ 上次主要介绍了操作系统的"管理"和操作系统对下的管理。本篇主要是对上的管理。 操作系统对上的管理 …