每周提问: HTTP DNS / NGINX 热更新 / LVS的几种代理模式 / 各种类型的数据库的擅长点/消息队列是如何实现削峰的 /机房分流策略

179 阅读9分钟

这是每周提问的第二周, 这些问题都是在平时的学习过程中遇到的不清晰的问题,希望通过这种方式,把这些模糊的问题变的清晰

HTTP DNS

什么是HTTP DNS

我觉得要解释清楚什么是HTTP DNS,还是要先从DNS开始,我们都知道DNS是主要功能是通过域名找到这个域名对应的IP地址,但是DNS的整个过程是有一些问题的

  • DNS缓存: 为了更高的效率,会把解析的结果放到缓存中,比如我们需要知道 www.baidu.com这个域名的ip地址,我们需要去找这个对应关系,当我们找到后,会把这个对应关系做一个缓存,当然这个缓存是有过期时间的,但是这个过程中,如果我们的域名换了一个IP地址,就会出现访问不到的情况,这也是DNS最大的问题,DNS解析延迟.
  • DNS劫持: 一些互联网服务提供商可能会修改DNS结果以显示自己的广告或阻止访问某些网站

HTTP DNS就是为了解决这个问题而出现的,具体的工作流程是:

image.png

  • 第一步: 通过一个IP地址访问HTTP DNS的服务器(这个IP地址是客户端和服务器协商放到源代码中的),在访问时也会带上实际要请求的地址比如例子中的 www.baidu.com
  • 第二步: HTTP DNS 收到这个请求后,将业务服务器的真实IP地址返回给调用方,比如这里的2.2.2.2
  • 第三步: 客户端访问业务服务器:2.2.2.2

这种是不是移动端用的多一些

从直观的感受来看,移动端使用IP地址的方式来访问没啥问题,但web端如果看到的是IP地址反而不合适了

  1. 显示和易用性问题:如果浏览器直接使用HTTP DNS并显示IP地址,用户体验会下降,因为IP地址通常不如域名直观易读。
  2. 现有Web架构的限制:在Web应用中,很多服务和功能依赖于传统的域名,例如Cookie的作用域、SSL证书的应用等,直接展示IP地址会破坏这些服务的正常运作。
  3. 浏览器的支持:传统的Web浏览器通常通过操作系统的DNS解析机制来获取IP地址,改变这一机制需要深入的系统修改和对浏览器行为的调整。

Nginx热更新

NGINX作为七层负载均衡器的代表,我们常常把他作为反向代理来使用,其实有更多的用法,比如,我们这里热更的目的其实是想让Nginx作为服务注册和服务发现来使用,比如我动态的更新了nginx.conf的upstream(当然用lua脚本更新,手动更新太慢了,而且很容易出现人为错误),通过热更新的方式,让访问者动态的访问到新配置的服务器 做法其实很简单 nginx -s reload这一命令会向NGINX主进程发送一个HUP信号,主进程在接收到这个信号后会重新读取配置文件,并以新的配置启动新的工作进程,同时优雅地关闭旧的工作进程,以确保现有请求的处理不中断。 当然通过nginx来做服务注册和服务发现的方式并不推荐,特别是集群的规模比较大的时候,因为实例的状态变化太大了,可能会陷入"更新风暴"中.

LVS的几种代理模式

NGINX是七层的负载均衡器,而LVS是四层的负载均衡,LVS的工作的层次是在操作系统中,所以性能更高,使用LVS的作用主要是为了消除NGINX的单点 如下图:

image.png 这是没有LVS的情况下,NGINX做了一层负载均衡,当流量特别高的时候,单个的NGINX可能会被大打挂,这时候我们需要对NGINX做集群,单点就会转移到更早的地方,比如我们这里的LVS上

image.png 当然消除LVS单点问题的方法也有,比如在DNS上对一个域名配置多个IP地址,路由到不同的LVS上,实现流量均摊

LVS的几种代理模式

  • NAT: LVS收到请求后,修改目标IP地址的方式将请求转发,在服务器返回时LVS先接收到响应,然后再由LVS响应给客户端 image.png
  • IP隧道: LVS将请求包再次封装成一个新的包,这个包的目标IP地址就是真实的服务器IP地址,等真实服务器收到请求后,解开这个包,就获得了请求地址,这样响应请求时就可以绕过LVS,这样性能会更好一些 image.png
  • DR模式: 在DR模式下,LVS只负责将请求分发给后端服务器,后端服务器直接将响应返回给客户端。这个模式需要LVS和所有的后端服务器在同一个物理网络中。

各种类型的数据库擅长点

1. 关系型数据库(RDBMS)

  • 代表产品: MySQL、PostgreSQL、Oracle、Microsoft SQL Server
  • 擅长领域:
    • 结构化数据: 因为它们的基础是表和关系,非常适合管理结构化数据。
    • 事务处理: 提供强大的事务支持(ACID属性),适合需要高可靠性的数据操作。
    • 复杂查询: 支持复杂的查询操作,适用于需要跨多个表进行复杂联接和计算的场景。

2. 文档数据库

  • 代表产品: MongoDB、Couchbase、RavenDB
  • 擅长领域:
    • 灵活的数据模式: 允许存储具有不同结构的文档,适合于变化频繁的数据。
    • 嵌套数据结构: 可以直接存储嵌套的数据结构,如JSON,非常适合处理复杂的数据和对象。
    • 快速开发: 由于其灵活性,开发人员不需要频繁更改数据库模式,从而加快开发速度。

3. 列数据库(列簇数据库)

  • 代表产品: Apache HBase、Apache Cassandra、Google Bigtable
  • 擅长领域:
    • 大规模数据读取与写入: 设计为处理非常大的数据集和高吞吐量的写入操作。
    • 时间序列数据: 非常适合存储和检索时间序列数据,适用于物联网等领域。
    • 分析和聚合操作: 优化了列式存储,支持高效的分析查询。

4. 图数据库

  • 代表产品: Neo4j、Amazon Neptune、ArangoDB

  • 擅长领域:

    • 图形技术: 自然适用于建模和处理连接与关系紧密网状的数据,如社交网络或推荐引擎。
    • 路径查询: 提供高效的路径和关联查询能力。
    • 数据互联: 当数据关系比数据本身更重要时,图数据库可以提供更简易和直观的解决方案。

消息队列是如何实现削峰的

我们找到消息队列其中一个用处就是削峰,比如服务器的QPS是100,有一个时间点,突然来了1000的请求,这时候很容易就把服务器打挂了,所以这时候把请求想放到消息队列中,然后再慢慢的把请求放给服务器,但其中的一些细节我不是很清晰,比如消息队列是如何知道服务器的处理能力的呢?

简单的说 消息队列和服务器有两种交互方式

定时拉取

比如访问器每隔1秒定时的去消息队列中拉取20个请求,让服务器处理请求,这个过程中可以实现动态拉取,比如我拉取了20个请求,等到下一次拉取时我查看CPU和内存的使用量,如果高了,就少拉点,如果正常就多一点,这个类似于TCP的请求窗口

消息队列主动推送

和主动拉取请求差不多,这个也是通过服务器的处理能力,设定消息队列单位时间内推送的数量

主动丢弃

其实使用了消息队列还是会出现消息丢弃的情况,比如消息队列满了,请求还是会被丢弃,我们使用消息队列是为了保护服务器不被打挂,在上周的提问中,有一个问题就是,服务器能处理10个请求,来了100个请求,为什么不是完成了10个请求,另外90个请求超时,而是大概率都会超时呢? 答案是这些等待的请求也消耗了大量的资源,如果我们使用了消息队列就基本上能实现服务器能处理10个请求,来了100个请求,为什么不是完成了10个请求,另外90个请求超时

机房分流策略

是这样的,现在服务器的机房实现了 "同城双活" 在一个城市部署了两个机房,两个机房都会提供服务,如何实现负载均衡呢?

  • DNS: 对同一个域名配置不同的IP地址,通过不同的网络或地区特点返回不同的IP地址,但这个修改延迟比较高,当其中一个机房出现故障,需要转移请求时候会有延迟
  • 客户端分流 HTTP DNS: 上面有对HTTP DNS有解释,大致是访问域名改成访问一个固定的IP地址,这个IP地址通过你请求的参数来给你分流,访问不同的机房,实现负载均衡,这个IP地址在不同的机房都提供这个服务,客户端访问A机房如果一直是不成功的,则可以暂时认定A机房出现问题了,可以转向去访问B机房的IP,这其实是客户端的主动容灾策略.

这里说机房的分流策略,别的地方分流策略也差不多.多是异曲同工,都可以借鉴这种思路.