服务端学习笔记(1)

2 篇文章 0 订阅

服务端问题集合

最近开发任务中需要用ts写一些后端的接口,随着开发的逐渐进行,需要把后端的相关知识进行重新汇总,也发现自己有很多已经遗忘的地方,特此记录


2020/04/06 add openAPI


2020/04/13 add Springboot&SSM框架


2020/05/06 add SLA


2020/06/02 add curl


2020/06/05 add 集成测试 VS 单元测试


2020/06/07 add code review


2020/06/17 add tips


2020/06/18 add CDN 和 存储的区别


2020/06/26 add 接口透传,post/put/delete


2020/07/13 add OAuth, OpenID, JWT, Session


2020/09/04 add CDN 相关内容


2020/09/17 add 面向对象(封装、继承、多态)


2020/09/20 add 泛域名


2021/01/19 add fallback


2021/09/30 add 超时监测


fallback

fallback 是用于出错时候进行的应急措施,我们可以用它来实现在出错的时候来进行回退操作。

泛域名

泛域名

泛域名主要用于泛域名解析,比如用户的域名是abc.com,那么我们将主机名设置为’ * ',IP解析到比如:218.104.78.100,大家都知道 ‘*’ 是通配符,他表明abc.com之前的所有子域名都将解析到218.104.78.100,这就意味着例如输入bbs.abc.com或者123.abc.com或者123.234.abc.com都将解析到218.104.78.100,这里需要说明的是,在我们系统里面如果单独设置一个子域名解析,比如将主机名设置为mail,单独解析到218.104.78.79,那么该解析记录优先。

面向对象

最近组内开始上 golang 版本的云服务,特别的记录一下在学习一门语言过程中所遇到的一些问题和想法

面向对象与面向过程的区别

面向对象:就是构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。常见的 OO 语言有 java/c++/c#
/python 等

image

面向过程:不同于面向对象,面向过程分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。常见的 PO 语言有 C 等

image

image

面向对象(封装,继承,重写,重载和多态)

JavaScript封装、继承和多态实现

封装

  • 封装:隐藏对象的属性和实现细节,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏
  • 封装的好处:隐藏类的实现细节,让使用者只能通过程序员规定的方法来访问数据,可以方便的加入存取控制语句,限制不合理操作。
  • JavaScript 实现封装
class Person {
 constructor(name, sex, age) {
 this.name = name;
 this.sex = sex;
 this.age = age;
 }

 walk() {
 if (this.age <= 2) {
 return console.log('我不会走路');
 }

 if (this.age >2 && this.age < 4) {
 return console.log('我会走路了');
 }

 return console.log('走路');
 }

 study(skill) {
        console.log('学习' + skill);
 }

 introduce() {
        console.log(`我是${this.name},我是一个${this.sex === 'male' ? "男" : "女"}孩,今年${this.age}岁了。`);
 }
 // 关于私有方法和私有属性
 // [es6 私有方法和私有属性](https://es6.ruanyifeng.com/#docs/class#%E7%A7%81%E6%9C%89%E6%96%B9%E6%B3%95%E5%92%8C%E7%A7%81%E6%9C%89%E5%B1%9E%E6%80%A7)
}


// 调用方式
// new关键字创建实例
var p = new Person('小名', 'male', 10);
p.walk(); // 走路
p.introduce();
// 直接调用创建
// var p1 = Person('小红', 'female', 9); // TypeError: Class constructor Person cannot be invoked without 'new'
// class定义的不能直接调用,只能通过new关键字实例化后调用

console.log(typeof Person); // function

继承

  • 继承可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
  • JavaScript 实现继承
class Boy extends Person {
 constructor(name, age) {
 super(name, 'male', age);
 }

 doHouseWork() {
        console.log('我在做家务');
 }
}
var boy = new Boy('汤姆', 14);
boy.introduce(); // 我是汤姆,我是一个男孩,今年12岁了。
boy.doHouseWork();// 我在做家务
console.log(boy instanceof Boy);// true

多态

  • 多态就是指一个类实例的相同方法在不同情形有不同表现形式。

  • 多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。

  • OOP 中多态主要通过抽象类和抽象函数实现的。传统意义的多态通过派生(子)类继承并实现基(父)类中的抽象函数实现。(注:虚函数是 c++ 中的概念,目的是实现多态,Java 没这个概念,但是抽象函数就是纯虚函数)

  • 多态的实现方式:

    • 方式一:重写:
    • 方式二:接口
    • 方式三:抽象类和抽象方法
  • javascript 实现多态:

    function Add() {
        function zero() {
            return 10
        }
        function one(num) {
            return 10 + num
        }
        function two(num1, num2) {
            return num1 + num2
        }
        this.add = function () {
            var arg = arguments,
                len = arguments.length
            switch (len) {
                case 0:
                    return zero()
                case 1:
                    return one(arg[0])
                case 2:
                    return two(arg[0], arg[1])
            }
        }
    }
    // test
    var a = new Add()
    console.log(a.add()) // 10
    console.log(a.add(7)) // 17
    console.log(a.add(7, 9)) // 16

references:

Virtual Function in JAVA

重写

  • Override 即重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写
  • 子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
    重写方法不能抛出新的检查异常或者比被重写方法申明更加宽泛的异常。
  • 重写有一定的规则可循

重载

  • overloading 即重载是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
    每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。
    最常用的地方就是构造器的重载。

  • JavaScript 实现重载(js 实现的多态正是一种重载方式)

  • 贴一个链接,闭包实现重载 JavaScript实现函数重载

image

OAuth, OpenID, JWT, Session

浅谈SAML, OAuth, OpenID和SSO, JWT和Session零壹技术栈

token

Token 即使是在计算机领域中也有不同的定义,这里我们说的 token,是指 访问资源 的凭据。例如当你调用 Google API 时,需要带上有效 token 来表明你请求的 合法性。这个 Token 是 Google 给你的,这代表 Google 给你的 授权 使得你有能力访问 API 背后的 资源。使用方式如下:

  • HTTP Header Authorization
  • URL参数
  • Python函数库

image

SSO (Single sign-on)

通常公司内部会有非常多的平台供大家使用,比如人力资源,代码管理,日志监控,预算申请等等。如果每一个平台都实现自己的用户体系的话无疑是巨大的浪费,所以公司内部会有一套 公用的用户体系,用户只要登陆之后,就能够 访问所有的系统。这就是 单点登录.

SSO 是一类 解决方案 的统称,而在具体的实施方面,我们有两种策略可供选择:

  • SAML 2.0

  • OAuth 2.0

SAML 2.0 (Security Assertion Markup Language 安全断言标记语言)

image

SAML 2.0 并 不适用 于当下 跨平台 的场景,这也许与它产生的年代也有关系,它诞生于 2005 年,在那个时刻 HTTP POST 确实是最好的选择方案。

OAuth 2.0 (Open Authorization 开放授权)

从获取 token 到使用 token 访问接口。这其实是标准的 OAuth2.0 机制下访问 API 的流程.

OAuth 的本意是 一个应用 允许 另一个应用 在 用户授权 的情况下 访问自己的数据。
image

OAuth 和 OpenId 的区别
  • OAuth: 用于 授权(Authorisation),允许 被授权方 访问 授权方 的 用户数据。
  • OpenID: 只用于 身份认证(Authentication),允许你以 同一个账户 在 多个网站登陆。它仅仅是为你的 合法身份 背书,当你以 Facebook 账号登陆某个站点之后,该站点 无权访问 你的在 Facebook 上的 数据。

JWT (JSON Web Token)

JWT与Session比较和作用

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

JWT 如何工作的

在认证的时候,当用户用他们的凭证成功登录以后,一个JSON Web Token将会被返回。此后,token就是用户凭证了,你必须非常小心以防止出现安全问题。一般而言,你保存令牌的时候不应该超过你所需要它的时间。

无论何时用户想要访问受保护的路由或者资源的时候,用户代理(通常是浏览器)都应该带上JWT,典型的,通常放在Authorization header中,用Bearer schema。此时header应该看起来是这样的:

Authorization: Bearer

服务器上的受保护的路由将会检查Authorization header中的JWT是否有效,如果有效,则用户可以访问受保护的资源。如果JWT包含足够多的必需的数据,那么就可以减少对某些操作的数据库查询的需要,尽管可能并不总是如此。

如果token是在授权头(Authorization header)中发送的,那么跨源资源共享(CORS)将不会成为问题,因为它不使用cookie

使用 JWT 的好处

用Token的好处

  • 无状态和可扩展性:

    • Tokens存储在客户端。完全无状态,可扩展。我们的负载均衡器可以将用户传递到任意服务器,因为在任何地方都没有状态或会话信息
  • 安全:Token不是Cookie。(The token, not a cookie.)

    • 每次请求的时候Token都会被发送。而且,由于没有Cookie被发送,还有助于防止CSRF攻击。即使在你的实现中将token存储到客户端的Cookie中,这个Cookie也只是一种存储机制,而非身份认证机制。没有基于会话的信息可以操作,因为我们没有会话!
  • token在一段时间以后会过期,这个时候用户需要重新登录。这有助于我们保持安全。还有一个概念叫token撤销,它允许我们根据相同的授权许可使特定的token甚至一组token无效。

JWT 和 session 区别

相同点是,它们都是存储用户信息;

不同点如下:

  • Session是在服务器端的,而JWT是在客户端的。

    • Session方式存储用户信息的最大问题在于要占用大量服务器内存,增加服务器的开销。JWT方式将用户状态分散到了客户端中,可以明显减轻服务端的内存压力。
    • Session的状态是存储在服务器端,客户端只有session id;而Token的状态是存储在客户端。
JWT与OAuth的区别
  • OAuth2是一种授权框架 ,JWT是一种认证协议
  • OAuth2用在使用第三方账号登录的情况(比如使用weibo, qq, github登录某个app),而JWT是用在前后端分离, 需要简单的对后台API进行保护时使用、

注: 无论使用哪种方式切记用HTTPS来保证数据的安全性

透传

顾名思义:即传递者不会对数据进行任何操作只做传递即可

透传消息和非透传消息

通信网络中的透传到底什么意思?

透传即是透明传送,即传送网络无论传输业务如何,只负责将需要传送的业务传送到目的节点,同时保证传输的质量即可,而不对传输的业务进行处理。透传消息,就是消息体格式及内容,对于传递的通道来说是不去过问的,通道只负责消息的传递,对消息不做任何处理,当客户端接收到透传消息后,由客户端自己来决定如何处理消息。正是因为透传消息可以自定义消息体,也可以自定义消息的展示方式及后续动作处理,所以弥补了通知栏消息的一些不足之处(通知栏消息是直接展示出来,相关的动作客户端无法捕获到)。

透传消息的特点

透传消息主要有如下几个方面的特点:

  1. 后台处理,用户无感知。
  2. 前台展示,提醒用户。
  3. 展示的多样化。

为什么要进行透传

透传一般都是用来读取远程的串口数据。例如:网吧内每个上网者都要刷身份证才能上网,但身份证数据库不可能放在每个网吧内。所以就将读卡器的串口数据通过透传回传到公安局,在公安局的平台上来比对身份证号码。

CDN

当前端使用了 CDN

image
也正是

CDN 与 存储

最近被封了一个域名导致一系列资源无法访问。顺带复习一下 CDN 的相关知识,CDN 和 存储并不是一样东西,而两者往往结合使用才能发挥出 CDN 的优势。

CDN是什么?使用CDN有什么优势?

一分钟看懂对象存储和CDN之间的关系

CDN(Content Delivery Network)是内容分发网络。基本思路就是在网络各处部署服务节点,系统实时地根据网络流量、负载状况、服务节点到用户的响应时间等信息,自动将用户请求到导向离用户最近的节点上。目的就是让用户就近取得数据,提高响应速度。

CDN本质上是一个分布式缓存系统,每个服务节点上都缓存了源站的一部分数据,也就是用户最近经常访问的数据。这样大部分用户请求其实都是在CDN边缘节点上完成,并没有达到源站,这样减少了响应时间,也减轻了源站的负担,可以实现高流量、大并发的网站访问。

CDN对动态资源是无效的,主要适合对静态资源的访问加速。比如一些网页内容需要数据查询才能获得,而每次要获得查询结果都要经过数据库的操作,再经过Web应用服务器的一些逻辑处理才能得到,这样就没法用CDN来加速。因为每次请求的数据都不一样,缓存过去访问过的数据没有意义。

随着点播、直播等视频类应用的红火,CDN又迎来了一个新的增长点。直播平台都需要CDN来加速视频播放,可以说直播提高了CDN服务商和网络主播的收入。

我们知道,对象存储里面存的就是一些图片、视频、文件等等,都是静态数据,正好适合用CDN做加速。我们要做的就是购买CDN服务,并把我们的静态数据URL添加到CDN的加速域名列表中

CDN主要应用于站点加速,提高网站中静态数据的访问性能,比如图片、音频、视频、静态HTML网页等。网站静态数据以前一般是用文件存储的形式保存,现在则主要用对象存储

以图片存储为例,简单说,对象存储是存图片的,CDN是加速下载图片的。对象存储+CDN,已经成为互联网应用的一个必不可少的组成部分。

CDN tips

一个文件请求到服务器CDN的过程
为了使用CDN缓存,我们至少要对静态资源的部署作出两项改变:
将静态资源部署到不同网络线路的服务器中,以加速对应网络中CDN节点无缓存时回源的速度
加载静态资源时使用与页面不同的域名,一方面是便于接入为CDN而设置的智能DNS解析服务,另一方面因为静态资源和主页面不同域,这样加载资源的HTTP请求就不会带上主页面中的cookie等数据,减少了数据传输量,又进一步加快网络访问。

post put请求区别

POST 和 PUT 方法区别

  • 新建一条记录的话就用post,
  • 更新一条记录的话就用put.
  1. POST 方法被用于请求源服务器接受请求中的实体作为请求资源的一个新的从属物

POST方法的实际功能是由服务器决定的,并且经常依赖于请求URI(Request-URI)。POST提交的实体是请求URI的从属物,就好像一个文件从属于一个目录,一篇新闻文章从属于一个新闻组,或者一条记录从属于一个数据库。POST方法执行的动作可能不会对请求URI所指的资源起作用。在这种情况下,200(成功)或者204(没有内容)将是适合的响应状态,这依赖于响应是否包含一个描述结果的实体。如果资源被源服务器创建,响应应该是201(Created)并且包含一个实体,此实体描述了请求的状态。并且引用了这个新资源和一个Location头域。POST方法的响应是不可缓存的。除非响应里有合适的Cache-Control或者Expires头域。然而,303(见其他)响应能被用户代理利用去获得可缓存的响应。

  1. PUT 方法 请求服务器去把请求里的实体存储在请求URI(Request-URI)标识下。

如果请求URI(Request-URI)指定的的资源已经在源服务器上存在,那么此请求里的实体应该被当作是源服务器关于此URI所指定资源实体的最新修改版本。如果请求URI(Request-URI)指定的资源不存在,并且此URI被用户代理定义为一个新资源,那么源服务器就应该根据请求里的实体创建一个此URI所标识下的资源。如果一个新的资源被创建了,源服务器必须能向用户代理(user agent) 发送201(已创建)响应。如果已存在的资源被改变了,那么源服务器应该发送200(Ok)或者204(无内容)响应。如果资源不能根据请求URI创建或者改变,一个合适的错误响应应该给出以反应问题的性质。实体的接收者不能忽略任何它不理解和不能实现的Content-*(如:Content-Range)头域,并且必须返回501(没有被实现)响应。如果请求穿过一个缓存(cache),并且此请求URI(Request-URI)指示了一个或多个当前缓存的实体,那么这些实体应该被看作是旧的。PUT方法的响应是不可缓存的。

  1. post put 方法根本区别
  • POST请求的URI表示处理该封闭实体的资源,该资源可能是个数据接收过程、某种协议的网关、或者接收注解的独立实体。
  • PUT请求中的URI表示请求中封闭的实体-用户代理知道URI的目标,并且服务器无法将请求应用到其他资源。如果服务器希望该请求应用到另一个URI,就必须发送一个301响应;用户代理可通过自己的判断来决定是否转发该请求。
  1. delete 请求:用于服务端删除一个资源,一般在 URL 中制定删除的 id 即可,一般不用请求体。Postman工具——请求与响应

tips

快速判断文件类型


file fileNamexx # 即文件名称

code review

在工作中也有利用 ts 写后端的场景,随着同事 codeReview 的建议,逐渐提高自己对服务端代码的认识

  • 避免在遍历中再请求其他接口
    • 此时会造成数据返回缓慢
// 以下这种写法不推荐使用
_.each(fn,item=>{
    item['ctime']= await this.xxx
})
// 推荐一次请求 放在一个对象中,然后用某个字段进行匹配的方式
  • 避免获取数组的第几个值
    • 解决方式:
    • 查数据库表的时候通过时间降序查出即丰富查询条件
// 熟练使用开发文档。比如可以定义 projection 去获取指定字段并排序等等
db.collection.find(query, projection).sort()
  • 进行判断变量存在不存在
    • 相比于 js 进行判断变量存在与否的繁琐,typescript 的 optional-chain 方便了许多
let x = foo?.bar.baz();
// 等同于
let x = (foo === null || foo === undefined) ?
    undefined :
    foo.bar.baz();
  • 类型检查,使用定义好的常量 enum 进行枚举
export enum Status {
  NORMAL = 'normal',
  DELETED = 'deleted',
}
// 以及 等等
Joi.string().valid([a,b,c])

集成测试 VS 单元测试

单元测试:

  • 是白盒测试即测试时代码对测试者透明
  • 针对单一功能

集成测试:

  • 是黑盒测试即测试时测试者看不到内部代码结构
  • 针对整体模块功能

image
image

curl

curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。

它的功能非常强大,命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。

具体应用指南可以参考 curl 的用法指南

SLA

服务等级协议SLA到底是在说什么?

系统的常见性能指标,(响应时间和吞吐量,平均负载,SLA)

SLA(Service Level Agreement)服务等级协议:

是双方的一种约定,是一种服务可用性的指标。服务可用性也是用百分比表示,但是与TP线含义不同

  • tp99%表示 满足99%的请求所用的最大响应时间

  • 可用性99%表示一定时间内提供服务的停机时间。

拿一年为例

1年 = 365天 = 8760小时

99.9 = 8760 * 0.1% = 8760 * 0.001 = 8.76小时

99.99 = 8760 * 0.0001 = 0.876小时 = 0.876 * 60 = 52.6分钟

99.999 = 8760 * 0.00001 = 0.0876小时 = 0.0876 * 60 = 5.26分钟

SLA提供的可用性越高,那么一年内停机的时间越小。高可用的一种量化指标

  • SLA可用性计算公式:可用性指标 = 正常请求 / 全部请求

  • 不可用指标统计:接口异常、超时、特定返回值异常。也就是说这些都是不正常请求

既然SLA是保证服务的可用性的,那我把服务响应时间调成N高,岂不是美滋滋,可用性大大的升,嘿嘿,想一想都(≧▽≦)/激动

哼,小样,在SLA的基础有有个SLO (服务等级目标)

准确的说SLA = SLO + 后果

SLO指定了服务所提供功能的一种期望状态。SLO里面应该包含什么呢?所有能够描述服务应该提供什么样功能的信息。服务提供者用它来指定系统的预期状态

上面太官方,说个例子

比如以下SLO:

每分钟平均qps > 100k/s

99% 访问延迟 < 500ms

99% 每分钟带宽 > 200MB/s

所以现在很清晰了,SLO定义的这个服务要达到的指标,再次基础上定义SLA,服务的可用性。当然还有个指标是SLI,这是服务测量指标的意思,SLO使用SLI定义,按上面的例子,SLI就是qps,延迟,带宽

清楚了SLO,那么既然SLA = SLO + 后果

后果是啥?,后果是一种奖惩措施,例如Amazon,如果达不到SLA的承诺,Amazon会提供服务补偿,如果达不到 99.9%的服务水平,那么Amazon将减免下个月10%的费用。如果可用性下降到99.0%以下,换算后相当于一个月内至少有将近7个小时无法服务, 那么Amazon将减免25%的费用.

接口

Java 接口

接口(英文:Interface),在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。

除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。

接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

接口与类相似点:

  • 一个接口可以有多个方法。
  • 接口文件保存在 .java 结尾的文件中,文件名使用接口名。
  • 接口的字节码文件保存在 .class 结尾的文件中。
  • 接口相应的字节码文件必须在与包名称相匹配的目录结构中。

接口与类的区别:

  • 接口不能用于实例化对象。
  • 接口没有构造方法。
  • 接口中所有的方法必须是抽象方法。
  • 接口不能包含成员变量,除了 static 和 final 变量。
  • 接口不是被类继承了,而是要被类实现
  • 接口支持多继承。

接口特性

  • 接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错)。
  • 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
  • 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法

抽象类和接口的区别

  1. 抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行
  2. 抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
  3. 接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
  4. 一个类只能继承一个抽象类,而一个类却可以实现多个接口。

抽象类和类的区别

抽象类和普通类的区别-Gtcxy

  • 抽象类是不能被实例化的,就是不能用new调出构造方法创建对象,而普通类则反之
  • 抽象类的访问权限限于Public和Protected,因为抽象类的方法是需要继承之后让子类去实现的,如果为Private,则无法被子类继承,子类也无法实现该方法
  • 如果一个类继承于抽象类,则该子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则必须将子类也定义为abstract类。
btw

一个类实现接口和继承抽象类对于抽象方法的实现原则是相同的:

(1)如果这个类是个普通类,那么必须实现这个接口/抽象类的所有抽象方法;

(2)如果这个类是个抽象类,那么不必实现这个接口/抽象类的抽象方法,因为抽象类中可以定义抽象方法。

FAAS AWS

references

FaaS介绍

IaaS, PaaS, SaaS, BaaS, Faas

AWS:amazon web service亚马逊云服务

FAAS: Functions as a Service

函数即服务

无服务器计算,当前使用最广泛的是AWS的Lambada。

服务商提供一个平台,允许客户开发、运行和管理应用程序功能,而无需构建和维护通常与开发和启动应用程序相关的基础架构的复杂性。 按照此模型构建应用程序是实现“无服务器”体系结构的一种方式,通常在构建微服务应用程序时使用.

API gateway

APIGateway 简介

是什么

APIGateway 即API网关,所有请求首先会经过这个网关,然后到达后端服务,有点类似于Facade模式。API网关作为系统接口对外的统一出口,可以减少调用方对服务实现的感知。

没有API网关时的结系统构如下图:由图可以看出,在没有API网关作为统一出口的情况下,需要调用方自己组合各种服务,而且容易让调用方感知后端各种服务的存在。

image[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8JTAXYXS-1632987432867)(https://note.youdao.com/favicon.ico)]

插播:何为facade模式:设计模式的一种

设计模式:外观(Facade)模式

加入了API网关之后:

image

用来做什么

1.统一对外接口:
当用户需要集成不同产品或者服务之间的功能,调用不同服务提供的能力。利用APIGateway可以让用户在不感知服务边缘的情况下,利用统一的接口组装服务。
对于公司内部不同的服务,提供的接口可能在风格上存在一定的差异,通过APIGateway可以统一这种差异。 当内部服务修改时,可以通过APIGateway进行适配,不需要调用方进行调整
减少对外暴露服务可以增加系统安全性。

2.统一鉴权:
通过APIGateway对访问进行统一鉴权,不需要每个应用单独对调用方进行鉴权,应用可以专注业务。

3.服务注册与授权:
可以控制调用方可以使用和不可以使用的服务。

4.服务限流:
通过APIGateway可以对调用方调用每个接口的每日调用及总调用次数限制

5.全链路跟踪:
通过APIGateway提供的唯一请求Id,监控调用流程,以及调用的响应时间

有哪些在做的

spring zuul

kong

引申:对于微服务的理解

何为微服务?微服务架构的优势,SpringCloud简介

10分钟读懂何为分布式、微服务和集群!

微服务

微服务架构:就是将原来的单体应用按义务范围来进行划分,划分为多个小model,每个微服务运行在自己的进程中,不相互影响,通过完全自动化部署来独立部署。并使用轻量级机制通信,通常是HTTP RESTUFUL API。可对各个微服务进行集中管理。这些小model可以使用不同的编程语言,以及不同的存储技术。微服务架构是分布式架构。

微服务架构的优点

按业务划分的微服务单元独立部署,运行在独立的进程中,服务与服务之间没有任何耦合,有很好的扩展性和复用性
++服务与服务之间通常采用HTTP通信++,这种通信机制与平台和语言无关(可以使用不同的编程语言和存储方法)。也可以采用轻量级的消息总线来通信,如RabbitMQ、Kafaka消息队列等等,数据格式一般都采用JSON
++每个微服务有自己的数据库,服务之间数据库是独立的
微服务一般采用自动化部署工具部署。Docker容器技术是微服务最佳部署的容器。
服务集中化管理(服务注册与发现Eureka、Zookeeper、Consul),监控(服务运行状况监控Spring-Boot-Admin-Server)
微服务架构是分布式架构++

微服务架构的缺点

项目构建复杂程度远高于单体应用
分布式系统中难保证数据一致性,一般情况下,少用分布式事物
服务部署比单体应用复杂
微服务架构难题及解决办法:

服务之间故障传播影响:譬如A服务调用了B服务,但是B服务因为网络或其他原因迟迟没有响应,容易引起服务的雪崩效应 — >采用“熔断机制”,快速报错
分布式事物:事物失败容易导致数据不一致 — >采用“两阶段提交”

微服务架构难题及解决办法

服务之间故障传播影响:譬如A服务调用了B服务,但是B服务因为网络或其他原因迟迟没有响应,容易引起服务的雪崩效应 — >采用“熔断机制”,快速报错
分布式事物:事物失败容易导致数据不一致 — >采用“两阶段提交”

传统单体架构的缺陷

传统的单体应用,将所有功能的表示层、业务逻辑层,数据访问层,包括静态资源等等全部糅合在一个工程里面,编译,打包,部署在单台服务器上上线,比如打成war包放在Tomcat的webapp目录中部署项目。这样的项目开发部署适合小型项目,系统功能不复杂,访问量不大的情况下有绝对的优势。开发速度快,运维方便。但是当业务越来越复杂,功能越来越多,参与的开发人员越来越多,就暴露出问题了:

  • 业务变复杂,代码量增大,代码可读性,可维护性,可扩展性下降。万一要新同事接手代码,理解起来花很多时间
  • 测试难度增大
  • 单体应用并发能力有限,访问量高了用户体验差
  • 单体应用容错率低,万一哪里出错,可能导致整个项目就崩了
    缓解措施:

将单体应用做集群部署,添加负载均衡服务器(例如Nginx反向代理转发请求)可稍微缓解以上3,4条缺点,但是还是不能完美解决问题

open API

references:

Openapi 接口设计思路

如何设计一个开放平台openapi?

什么是 openAPI ?

什么是open API

Open API即开放API,也称开放平台。 所谓的开放API(OpenAPI)是服务型网站常见的一种应用,网站的服务商将自己的网站服务封装成一系列API(Application Programming Interface,应用编程接口)开放出去,供第三方开发者使用,这种行为就叫做开放网站的API,所开放的API就被称作OpenAPI(开放API)

考量条目:

  • 签名鉴权(我需要知道请求我的是谁,有没有访问这个接口的权限)
  • 流量控制(我不可能让你随随便便就无节制的访问我,我要能随时关停你)
  • 请求转发(请求过来的 url,需要找到真正的业务处理逻辑,api最好只负责接口的规范,不负责业务的实现)
  • 日志处理(你可以保持沉默,但你说的每一句话都会成为呈堂供证)
  • 异常处理(即使老子内部出了问题,你也不会看到我的异常堆栈信息,我会告诉你我病了,请稍后再试)
  • 参数规范(顺我者倡,逆我者亡)
  • 多机部署(我有九条命)
  • 异步回调(别想阻塞我,但我可以玩死你)
  • 错误信息(你要认识到自己错误)
DDOS攻击

分布式拒绝服务攻击

分布式拒绝服务攻击(英文意思是Distributed Denial of Service,简称DDoS)是指处于不同位置的多个攻击者同时向一个或数个目标发动攻击或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。由于攻击的发出点是分布在不同地方的,这类攻击称为分布式拒绝服务攻击,其中的攻击者可以有多个

为什么要建立开放平台

openapi在10年左右主要还是应用在国内的互联网公司主要集中在社交平台,因为社交平台的用户数据对于规模较小的公司是最有价值的资源,一下子可以降低获客成本,并且获得了这些社交平台开放的其他能力。2010年以后国内的开放平台开始摆脱社交这一单一的开放平台场景,逐渐的地图、新闻门户、电商等很多行业都开放了相关的核心api。

开放平台关键功能模块

服务接入网关
服务管理
服务代理
服务mesh up

mesh up:

mashup是糅合,是当今网络上新出现的一种网络现象,将两种以上使用公共或者私有数据库的web应用,加在一起,形成一个整合应用。一般使用源应用的api接口,或者是一些rss输出(含atom)作为内容源,合并的web应用用什么技术,则没有什么限制。

服务组合:各个源系统提供的接口可能都是简单的,需要对源系统接口进行组合后再对外进行开放。

oauth

OAuth协议致力于使网站和应用程序(统称为消费方)能够在无须用户透露其认证证书的情况下,通过API访问某个web服务(统称为服务提供方)的受保护资源。更一般地说,OAuth为API认证提供了一个可自由实现且通用的方法。

开放平台通过oauth协议来进行鉴权,当然你也可以用自己的token体系进行鉴权,不过目前主流的开放平台都是使用oauth鉴权,这里建议也是使用oauth进行鉴权,这样开发者在接入的时候也会比较容易理解,不用重新学习。oauth必须要实现以下基础服务:

  • accesstoken发放:对于通过安全登录的终端需要进行accesstoken的发放,并在系统中进行记录,系统中需要设计一个accesstoken的生成方案,生成的token需要加入userid作为因子,这样可以将token和userid进行绑定起来进行权限控制。
  • accesstoken校验:token的校验需要实现有效期校验和登录有效性校验。
  • refreshtoken更换accesstoken:当accesstoken过期后,开发者在调用端可以通过refreshtoken更换新的accesstoken实现登陆有效性的延期。
服务注册发现
安全
开发者门户
开放平台内管
沙箱

沙箱用大白话讲其实就是一个提供交易模拟的测试环境,里面的数据都是模拟的,交易路径也是比较固定的。

开放平台为什么需要一个沙箱?
  • 首先开放平台服务接口是对外开放的,想想我们在开发过程中是怎么开发和测试其他系统提供的接口的,开发肯定是先和对方系统在开发、测试环境联调接口,联调测试通了再上测试环境再上生产环境,但是我们开放平台因为本身不提供业务功能,真正的业务功能都是后台源系统提供的,生产环境可以从开放平台到业务生产系统都搭建完整的一套,但是对于测试环境,外部开发者是没办法连接到我们内部测试系统的,那么如果在公网再搭建一套成本太高了,而且还需要进行测试数据管理也不太现实。所以就引出了沙箱的概念,沙箱就是给开发者提供了一个模拟的测试环境,后台其实是没有真实的业务源系统的,都是沙箱配置好报文固定返回,这样就解决了测试环境和开发者测试联调的问题。

测试沙箱也存在一个问题,就是数据不够真实,因为沙箱都是固定的业务逻辑和规则,返回的报文也是固定的,可能很多异常场景是无法测试到的,这些异常情况也只能在沙箱测试完成后,进行生产测试来避免。

Spring==>Springboot,SSH,SSM

最近在用ts开发后端,但对于服务端的内容其实是有很多的遗忘的,特此进行记录。

怎么区分

DAO model service controller层分别代表什么

SSM框架中Dao层,Mapper层,controller层,service层,model层,entity层都有什么作用

Spring Boot框架model层、dao层、service层、controller层分析设计

model
  • model层即数据库实体层,也被称为entity层,pojo层。
  • 一般数据库一张表对应一个实体类,类属性同表字段一一对应。

即model层=entity层。存放我们的实体类,与数据库中的属性值基本保持一致。

DAO
  • dao层即数据持久层,也被称为mapper层。
  • dao层的作用为访问数据库,向数据库发送sql语句,完成数据的增删改查任务。

mapper层=dao层,现在用mybatis逆向工程生成的mapper层,其实就是dao层。对数据库进行数据持久化操作,他的方法语句是直接针对数据库操作的,而service层是针对我们controller,也就是针对我们使用者。service的impl是把mapper和service进行整合的文件。

(多说一句,数据持久化操作就是指,把数据放到持久化的介质中,同时提供增删改查操作,比如数据通过hibernate插入到数据库中。)
service
  • service层即业务逻辑层。
  • service层的作用为完成功能设计。
  • service层调用dao层接口,接收dao层返回的数据,完成项目的基本功能设计。

即存放业务逻辑处理,也是一些关于数据库处理的操作,但不是直接和数据库打交道,他有接口还有接口的实现方法,在接口的实现方法中需要导入mapper层,mapper层是直接跟数据库打交道的,他也是个接口,只有方法名字,具体实现在mapper.xml文件里,service是供我们使用的方法。

controller
  • controller层即控制层。
  • controller层的功能为请求和响应控制。
  • controller层负责前后端交互,接受前端请求,调用service层,接收service层返回的数据,最后返回具体的页面和数据到客户端。

即控制器,导入service层,因为service中的方法是我们使用到的,controller通过接收前端传过来的参数进行业务操作,在返回一个指定的路径或者数据表。

在实际开发中的Service层可能被处理为实体Service层,而不是接口,业务逻辑直接写在Service(Class,不是Interface)层中,Controller直接调用Service,Service调用Mapper。

metrics 监测

通常我们都会在服务端项目中加入适当的埋点信息记录 metrics,最简单的比如成功失败率、响应时间等。

接口响应超过 60s 时上报

一种解决方式是:利用 node eventloop 特性,setTimeout callback 是 macro task, await、 promise then 是 micro task.代码执行到 setTimeout 开始计时 60s 后将其加入到任务队列

async function test() {
 const timer = setTimeout(() => {
 // record metrics
 }, 60*1000);
 
 // 业务逻辑
 await xxx.finally(()=>{  
     clearTimeout(timer);
 });
 
 console.info('end');
}

这样可以在业务逻辑执行较长时及时记录 60s 超时的点进行分析或报警。

  • 可以认为「业务逻辑」里面一定有一个宏任务是在 setTimeout 之后执行的,但不确定。可以后续继续补充
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值