服务

应用

有哪些应用服务的部署方式?分别有什么优缺点?

单主机多服务实例模式

这种部署是比较传统的方式。

优点:

资源使用率相对较高。多个服务实例共享服务器及其操作系统。 部署服务实例相对较快。

缺点 :

服务之间很少或者没有隔离。一个行为不当的服务实例可能会占用掉主机的所有内存或CPU。 部署服务的运维团队必须了解执行此操作的具体细节。这种复杂加大了部署过程中的错误风险。 由于这些明显的缺点所以我们尽量不采用这种方式。

单虚拟机单服务实例

这种方式将每个服务打包成一个虚拟机(VM)镜像。每个服务实例都是一个使用该VM镜像启动的VM。

优点 :

每个服务实例是完全隔离的。他有固定的CPU和内存,且不能从其他服务窃取资源。 可以利用成熟的云基础架构,包括负载均衡和自动扩展。 部署更加简单/可靠。虚拟机封装了服务的技术实现。一旦服务被打包成虚拟机他就成为一个黑盒子。VM的管理API成为部署服务的API, 运维团队只需要掌握VM的管理API即可。

缺点:

资源利用率较低。每个服务实例都有一整个VM开销,包括操作系统。 版本部署时间通常很慢。由于大小原因,VM镜像通常构建很慢,实例化也很慢,而且操作系统启动也需要一定的时间。

单容器单服务实例

每个服务实例都在自己的容器中运行。容器是一个操作系统级虚拟化机制比如Docker。从进程的角度来看,他们有自己的端口命名空间和根文件系统。可以限制容器的内存和CPU资源,甚至可以限制I/O速率。每个服务打包成容器镜像,通常每个物理主机上运行多个容器。

优点 :

隔离性,每个服务彼此隔离。可以轻松的监控每个容器所消耗的资源。 部署简单,不需要了解服务技术细节,主要掌握容器管理API即可。 快速构建。容器是轻量级技术,可以非常快速的构建。容器启动页很快,因为没有繁琐的操作系统引导机制。

缺点 :

容器技术还没有虚拟机技术那么成熟,不像VM那么安全,因为容器彼此共享了主机的OS内核。 需要自己管理容器基础架构以及可能运行的VM基础架构。

Serverless部署

AWS Lambda就是一个serveless部署技术示例。要部署微服务,请将其打包成ZIP文件上传给AWS Lambda。 还有对应的元数据,其中包括了被调用来处理请求的函数的名称。 AWS Lambda自动运行足够的微服务实例来处理请求。只需要根据每个请求所用时间和内存消耗来计费。 开发人员无需担心服务器、虚拟机或容器的任何方面。

该模式的优势 1、便捷,不需要对IT基础架构负任何责任,可以专注于开发应用程序。

该模式的缺点 1、不适用于部署长时间运行的服务,例如消耗第三方消息代理消息的服务。必须在300秒内完成。服务必须是无状态的,因为理论上,AWS Lambda可能为每个请求运行一个单独的实例。

参考:

如何部署微服务

Node应用如何容灾?

1.动态降频   wormhole主要消耗性能的地方就在模板引擎渲染这部分,在并发访问量大的情况下,频繁的模板渲染会导致系统负载急剧飙升,导致响应延迟。判断是否到达阀值,然后不走服务端渲染,全部客户端渲染。

2.CDN兜底 动态降频能够保证大部分情况下的快速响应;但是,如果集群全部宕机,则也无能为了。所以需要通过CDN来兜底。

3.限流

在应用层计数,超过阀值直接限流

4.多进程模型

是否采用多进程可以综合考虑:node应用的单进程和多进程模型有什么优缺点?。如果部署方式为虚拟机,可以考虑用多进程模型充分利用CPU数量;如果部署方式为docker配k8s,建议单进程,把稳定性保障交给k8s。部署方式的区别:有哪些应用服务的部署方式?分别有什么优缺点?

5.多集群部署

健康检查,要求每个节点实现一个健康检查的 http 接口,然后 Nginx Server 会定时地轮训这个 URL 来做检查,当返回的 status_code 非 200 时,认为节点宕机,不再导流到这台 Node 服务器。

6.各种监控

异常监控、性能报警等等。

参考:

天猫双11前端分享系列(二):天猫双11页面服务容灾方案大揭秘 · Issue #26 · tmallfe/tmallfe.github.io

部署node时如何充分利用服务器的多核

用node 的 cluster,用 k8s 也能部分利用多核性能。

参考pm2的fork模式和cluster模式的有什么区别?

服务端异常如何监控

比如用 sentry 监控异常,elk 打日志,prometheus 监控性能并用 alertmanager 报警,再写一个webhook到钉钉。

线上出现问题时如何在应用层面监控cpu和memory的信息?

利用各种第三方工具,参考如何回答性能优化的问题,才能打动阿里面试官? - 知乎

如何查看一个node的服务端应用的内存和CPU

可以参考普罗米修斯的node客户端实现:FunnyLiu/prom-client at readsource,基本就是运用各种node原生api来完成

ps / pidstat等传统linux命令,配合node内建的process.memoryUsage返回一个对象,包含了 Node 进程的内存占用信息。该对象包含四个字段,单位是字节。主要看heapUsed:

{ rss: 130772992,  // 总内存占用
  heapTotal: 121925632, // 堆占用的内存,包括用到的和没用到的。
  heapUsed: 106210400, // 用到的堆的部分
  external: 2984477 } // V8 引擎内部的 C++ 对象占用的内存。

当服务端的内存发生了OOM问题如何排查?

比如看 promethues,查看监控的突然高峰,看日志那段时候发生了什么,看有没有提交代码。然后可以具体分析代码片段,通过node自建的profiling和apachebench配合配合node内建profiling进行性能排查,其本质是基于v8的profiling

如何设计一个高可用的短链服务?

短链接实现的原理非常简单,可以概括为:

1、为每个原链接生成不重复的唯一短链接

2、将原链接和对应短链接成对保存到数据库

3、访问短链接时,web服务器将目标重定向到对应的原链接

需要思考的是:

1、数据体量大的时候怎样分库分表?

2、短链访问量大的时候怎么去加缓存…?

缓存采用redis自带的热点缓存算法。

3、怎么缩短网址,要不要可逆?

使用shortid这样的库,可以了解其原理。

网上比较流行的算法有两种 自增序列算法、 hash算法。

自增序列算法 也叫永不重复算法

设置 id 自增,一个 10进制 id 对应一个 62进制的数值,1对1,也就不会出现重复的情况。这个利用的就是低进制转化为高进制时,字符数会减少的特性。例如Twitter-Snowflake。

短址的长度一般设为 6 位,而每一位是由 [a - z, A - Z, 0 - 9] 总共 62 个字母组成的,所以 6 位的话,总共会有 62^6 ~= 568亿种组合,基本上够用了。

这种方式的缺点就是即使是同一输入,每次输出的结果也会不同,所以不便于统计,但是觉得不会重复。但不重复带来的问题就是数据库中数量也会大量增加

至于hash算法就有很多种了,几千种就不一一列举了,hash都有可能重复,但是可以一一对应。

谷歌的短链服务采用的算法应该是前者,而百度和新浪则是后者。

4、重定向是301还是302?

关于跳转,301 是永久重定向,302 是临时重定向。短地址一经生成就不会变化,所以用 301 是符合 http 语义的,搜索引擎也会收录,浏览器会记录跳转地址,301的话直接走了缓存,同时对服务器压力也会有一定减少。

但是如果使用了 301,我们就无法统计到短地址被点击的次数了,如果对数据统计有要求的话,使用302跳转可能比较好一些,302能快速回收内容便于监管。

参考:

如何快速搭建一个短链接服务? - 知乎

Twitter-Snowflake,64位自增ID算法详解 - 简书

短网址原理和实现 - 掘金

短网址(short URL)系统的原理及其实现

一般如何进行压力测试

简单的话用apachebench,系统性的可以考虑jmeter,用goreplay来回放线上流量。

设计一个node应用远程调试方案

使用SIGUSR1通知现有的Node进程,启用和访问V8调试器。(Node API文档)

使用docker killcommand,该命令实际上并没有杀死在Docker容器中运行的PID 1进程,而是向其发送Unix信号(默认情况下,它会发送SIGKILL)

参考:

新知识点!一文告诉你如何调试运行在Docker容器中的远程Node.js应用程序 - 灰信网(软件开发博客聚合)

k8s了解吗?基于k8s,设计一个node serverless方案(todo)