服务
应用
有哪些应用服务的部署方式?分别有什么优缺点?
单主机多服务实例模式
这种部署是比较传统的方式。
优点:
资源使用率相对较高。多个服务实例共享服务器及其操作系统。 部署服务实例相对较快。
缺点 :
服务之间很少或者没有隔离。一个行为不当的服务实例可能会占用掉主机的所有内存或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 也能部分利用多核性能。
服务端异常如何监控
比如用 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算法详解 - 简书
一般如何进行压力测试
简单的话用apachebench,系统性的可以考虑jmeter,用goreplay来回放线上流量。
设计一个node应用远程调试方案
使用SIGUSR1通知现有的Node进程,启用和访问V8调试器。(Node API文档)
使用docker killcommand,该命令实际上并没有杀死在Docker容器中运行的PID 1进程,而是向其发送Unix信号(默认情况下,它会发送SIGKILL)
参考:
新知识点!一文告诉你如何调试运行在Docker容器中的远程Node.js应用程序 - 灰信网(软件开发博客聚合)