learn more
Toggle navigation
learn more
主页
About Me
linux
docker
mysql
elk
归档
标签
notebook
2020-10-27 16:14:20
139
0
0
wang2020
## liunx ### process manager 1.systemctl stop sshd后为何连接的ssh未断开 sshd service文件定义的killMode设为process,表示只停止主进程,不停止任何sshd 子进程,即子进程打开的 SSH session 仍然保持连接 ### memory manager ### network manager ### security manager ### file system ## network ### tcp/ip ### https 实现原理 ### 加密技术基础 ## k8s ## java ### jvm内存  对于JVM的内存,有堆内内存和堆外内存之分。 对于堆内内存,是我们平常打交道最多的地方,因为我们大部分Java对象,都是在堆上分配的。一旦有溢出问题,使用jmap + mat等一系列猛如虎的操作,就可以方便快捷的发现问题。 ### java启动命令参数  Java 命令行提供了以下几种类型的选项 标准选项 非标准选项 高级运行选项 高级JIT编译选项 高级垃圾回收选项 高级可用性选项 (1) 标准选项被所有类型的JVM支持。标准选项用来做常规操作,如查看版本,设定class path等。 (2) 非标准选项一般是指Java HotSpot Virtual Machine特定的选项,不能保证被所有类型的JVM支持,该类选项使用时,以-X开头。 (3) 高级选项是用于Java HotSpot Virtual Machine特定区域调优的选项,同样不能保证被所有的JVM支持。该类选择使用时,以-XX开头。对于Boolean类型的选项,通过使用+表示选项生效,- 来标示选项无效。如-XX:+OptionName表示选项OptionName生效,-XX:-OptionName表示选项OptionName无效。 - 堆 -Xmx -Xms - 元空间 -XX:MaxMetaspaceSize -XX:MetaspaceSize - 栈 -Xss - 直接内存 -XX:MaxDirectMemorySize - JIT编译后代码存放 -XX:ReservedCodeCacheSize 常用参数: ``` -Xms64m -Xmx$jvmMaxHeapSize $opts -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/ ``` - -Duser.timezone=Asia/Shanghai 启动设置时区 用于:服务器时间正确,打印日志时间有问题 - -Dfile.encoding=UTF-8 编码格式 用于:解决乱码问题 - -Xms64m jvm堆的初始大小,默认为物理内存的1/64,最小为1M;可以指定单位,比如k、m,若不指定,则默认为字节 - -Xmx512m jvm堆的最大值,默认为物理内存的1/4或者1G,最小为2M;单位与-Xms一致。 - -Xss 设置单个线程栈的大小,一般默认为512k。 - -Xmn 设置堆(heap)的年轻代的初始值及最大值,单位与-Xms一致,年轻代是存储新对象的地址,也是GC发生得最频繁的地方,若设置过小,则会容易触发年轻代垃圾回收(minor gc),若设置过大,只触发full gc,则占用时间会很长,oracle建议是把年轻代设置在堆大小的四份之一到一半的。这命令同时设置了初始值和最大值,可以使用-XX:NewSize和-XX:MaxNewSiz来分别设置。 - -XX:+UnlockExperimentalVMOptions - -XX:+UseZGC 使用zgc垃圾收集器(ZGC垃圾收集器在 java 15正式发布) - -XX:+HeapDumpOnOutOfMemoryError 参数表示当JVM发生OOM时,自动生成DUMP文件。 - -XX:HeapDumpPath=/ 发生OOM时,dump出快照到文件 - -Dspring.profiles.active=$profiles ### jvm调优 基本概念 JVM把内存区分为堆区(heap)、栈区(stack)和方法区(method)。由于本文主要讲解JVM调优,因此我们可以简单的理解为,JVM中的堆区中存放的是实际的对象,是需要被GC的。其他的都无需GC。 jvm内存模型  从图中我们可以看到, 1、JVM实质上分为三大块,年轻代(YoungGen),年老代(Old Memory),及持久代(Perm,在Java8中被取消,我们不做深入介绍)。 2、垃圾回收GC,分为2种,一是Minor GC,可以可以称为YGC,即年轻代GC,当Eden区,还有一种称为Major GC,又称为FullGC。 3、GC原理: 我们可以看到年轻代包括Eden区(对象刚被new出来的时候,放到该区),S0和S1,是幸存者1区和幸存者2区,从名字可以看出,是当发生YGC,没有被任何其他对象所引用的对象将会从内存中被清除,还被其他对象引用的则放到幸存者区。当发生多次YGC,在S0、S1区多次没有被清楚的对象,则会被移到老年代区域。当老年代区域被占满的时候,则会发送FullGC。 无论是YGC或是FullGC,都会导致stop-the-world,即整个程序停止一些事务的处理,只有GC进程允许以进行垃圾回收,因此如果垃圾回收时间较长,部分web或socket程序,当终端连接的时候会报connetTimeOut或readTimeOut异常, 4、从JVM调优的角度来看,我们应该尽量避免发生YGC或FullGC,或者使得YGC和FullGC的时间足够的短。 ## elk/efk ### 架构 ### 调优 ## prometheus ### 架构  Prometheus从exporter拉取数据,或者间接地通过网关gateway拉取数据(如果在k8s内部署,可以使用服务发现的方式),它默认本地存储抓取的所有数据,并通过一定规则进行清理和整理数据,并把得到的结果存储到新的时间序列中,采集到的数据有两个去向,一个是报警,另一个是可视化。PromQL和其他API可视化地展示收集的数据,并通过Alertmanager提供报警能力。 #### 特点 - 多维数据模型(有metric名称和键值对确定的时间序列) - 灵活的查询语言 - 不依赖分布式存储 - 通过pull方式采集时间序列,通过http协议传输 - 支持通过中介网关的push时间序列的方式 - 监控数据通过服务或者静态配置来发现 - 支持图表和dashboard等多种方式 #### 组件内容 - Prometheus Server 负责从 Exporter 拉取和存储监控数据,并提供一套灵活的查询语言(PromQL) - Retrieval: 采样模块 TSDB: 存储模块默认本地存储为tsdb HTTP Server: 提供http接口查询和面板,默认端口为9090 Exporters/Jobs 负责收集目标对象(host, container…)的性能数据,并通过 HTTP 接口供 Prometheus Server 获取。支持数据库、硬件、消息中间件、存储系统、http服务器、jmx等。只要符合接口格式,就可以被采集。 - Short-lived jobs 瞬时任务的场景,无法通过pull方式拉取,需要使用push方式,与PushGateway搭配使用 - PushGateway 可选组件,主要用于短期的 jobs。由于这类 jobs 存在时间较短,可能在 Prometheus 来 pull 之前就消失了。为此,这次 jobs 可以直接向 Prometheus server 端推送它们的 metrics。这种方式主要用于服务层面的 metrics,对于机器层面的 metrices,需要使用 node exporter。 - 客户端sdk 官方提供的客户端类库有go、java、scala、python、ruby,其他还有很多第三方开发的类库,支持nodejs、php、erlang等 - PromDash 使用rails开发的dashboard,用于可视化指标数据,已废弃 - Alertmanager 从 Prometheus server 端接收到 alerts 后,会进行去除重复数据,分组,并路由到对收的接受方式,发出报警。常见的接收方式有:电子邮件,pagerduty,OpsGenie, webhook 等。 - Service Discovery 服务发现,Prometheus支持多种服务发现机制:文件,DNS,Consul,Kubernetes,OpenStack,EC2等等。基于服务发现的过程并不复杂,通过第三方提供的接口,Prometheus查询到需要监控的Target列表,然后轮训这些Target获取监控数据。 其大概的工作流程是: - Prometheus server 定期从配置好的 jobs 或者 exporters 中拉 metrics,或者接收来自 Pushgateway 发过来的 metrics,或者从其他的 Prometheus server 中拉 metrics。 - Prometheus server 在本地存储收集到的 metrics,并运行已定义好的 alert.rules,记录新的时间序列或者向 Alertmanager 推送警报。 - Alertmanager 根据配置文件,对接收到的警报进行处理,发出告警。 - 在图形界面中,可视化采集数据。 #### 关于pull和push Prometheus采集数据是用的pull也就是拉模型,通过HTTP协议去采集指标,只要应用系统能够提供HTTP接口就可以接入监控系统,相比于私有协议或二进制协议来说开发、简单。优点主要是: - 开发任何新功能,你甚至可以在电脑上查看你的监控 如果目标实例挂掉,你可以很快知道 - 你可以手动指定目标实例,并且在浏览器中查看他的健康状态 总体来说,Pull模式比Push模式更好一些,在监控系统中这也不是一个很重要的点。 - 如果要使用push的方式,可以使用Pushgateway的方式,如定时任务的采集。 对于定时任务这种短周期的指标采集,如果采用pull模式,可能造成任务结束了,Prometheus还没有来得及采集,这个时候可以使用加一个中转层,客户端推数据到Push Gateway缓存一下,由Prometheus从push gateway pull指标过来。(需要额外搭建Push Gateway,同时需要新增job去从gateway采数据) 推的代表有 ElasticSearch,InfluxDB,OpenTSDB 等,需要你从程序中将指标使用 TCP,UDP 等方式推送至相关监控应用,只是使用 TCP 的话,一旦监控应用挂掉或存在瓶颈,容易对应用本身产生影响,而使用 UDP 的话,虽然不用担心监控应用,但是容易丢数据。 拉的代表,主要代表就是 Prometheus,让我们不用担心监控应用本身的状态。而且,可以利用 DNS-SRV 或者 Consul 等服务发现功能就可以自动添加监控。 当然,InfluxDB 加上 collector,或者 ES 加上 metricbeat 也可以变为 『拉』,而 Prometheus 加上 Push Gateway 也可以变为 『推』。 #### 存储机制 Prometheus有着非常高效的时间序列数据存储方法,每个采样数据仅仅占用3.5byte左右空间,上百万条时间序列,30秒间隔,保留60天,大概花了200多G(引用官方PPT)。 Prometheus内部主要分为三大块,Retrieval是负责定时去暴露的目标页面上去抓取采样指标数据,Storage是负责将采样数据写磁盘,PromQL是Prometheus提供的查询语言模块。 Prometheus内置了一个基于本地存储的时间序列数据库。在Prometheus设计上,使用本地存储可以降低Prometheus部署和管理的复杂度同时减少高可用(HA)带来的复杂性。 在默认情况下,用户只需要部署多套Prometheus,采集相同的Targets即可实现基本的HA。同时由于Promethus高效的数据处理能力,单个Prometheus Server基本上能够应对大部分用户监控规模的需求。 同时为了适应数据持久化的问题,Prometheus提供了remote_write和remote_read的特性,支持将数据存储到远端和从远端读取数据。通过将监控与数据分离,Prometheus能够更好地进行弹性扩展。 ### 面试相关 ##MQ ### rabbitmq #### 架构原理  应用场景: 应用解耦,流量削峰,异步处理 解耦: 削峰 异步: #### 相关概念 - Broker:简单来说就是消息队列服务器实体。 - Exchange:消息交换机,它指定消息按什么规则,路由到哪个队列。 - Queue:消息队列载体,每个消息都会被投入到一个或多个队列。 - Binding:绑定,它的作用就是把exchange和queue按照路由规则绑定起来。 - Routing Key:路由关键字,exchange根据这个关键字进行消息投递。 - vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离。 - producer:消息生产者,就是投递消息的程序。 - consumer:消息消费者,就是接受消息的程序。 - channel:消息通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务。 #### 使用过程 AMQP模型中,消息在producer中产生,发送到MQ的exchange上,exchange根据配置的路由方式发到相应的Queue上,Queue又将消息发送给consumer,消息从queue到consumer有push和pull两种方式。 消息队列的使用过程大概如下: - 客户端连接到消息队列服务器,打开一个channel。 - 客户端声明一个exchange,并设置相关属性。 - 客户端声明一个queue,并设置相关属性。 - 客户端使用routing key,在exchange和queue之间建立好绑定关系。 - 客户端投递消息到exchange。 - exchange接收到消息后,就根据消息的key和已经设置的binding,进行消息路由,将消息投递到一个或多个队列里。 exchange也有几个类型,完全根据key进行投递的叫做Direct交换机,例如,绑定时设置了routing key为”abc”,那么客户端提交的消息,只有设置了key为”abc”的才会投递到队列。 ### 面试相关 1.为什么使用MQ? 主要是:解耦,异步,削峰 - 解耦: 就是一个系统或者一个模块,调用了多个系统或者模块,互相之间的调用很复杂,维护起来很麻烦。但是其实这个调用是不需要直接同步调用接口的,如果用 MQ 给它异步化解耦。 - 异步:A 系统接收一个请求,需要在自己本地写库,还需要在 BCD 三个系统写库,自己本地写库要 3ms,BCD 三个系统分别写库要 300ms、450ms、200ms。最终请求总延时是 3 + 300 + 450 + 200 = 953ms,接近 1s,用户感觉搞个什么东西,慢死了慢死了。用户通过浏览器发起请求。如果使用 MQ,那么 A 系统连续发送 3 条消息到 MQ 队列中,假如耗时 5ms,A 系统从接受一个请求到返回响应给用户,总时长是 3 + 5 = 8ms。 - 削峰:减少高峰时期对服务器压力。 2.mq优缺点 优点上面已经说了,就是在特殊场景下有其对应的好处,解耦、异步、削峰。 缺点有以下几个: - 系统可用性降低 系统引入的外部依赖越多,越容易挂掉。万一 MQ 挂了,MQ 一挂,整套系统崩溃,你不就完了? - 系统复杂度提高 硬生生加个 MQ 进来,你怎么保证消息没有重复消费?怎么处理消息丢失的情况?怎么保证消息传递的顺序性?问题一大堆。 - 一致性问题 A 系统处理完了直接返回成功了,人都以为你这个请求就成功了;但是问题是,要是 BCD 三个系统那里,BD 两个系统写库成功了,结果 C 系统写库失败了,咋整?你这数据就不一致了。 3.Kafka、ActiveMQ、RabbitMQ、RocketMQ 都有什么区别? 对于吞吐量来说kafka和RocketMQ支撑高吞吐,ActiveMQ和RabbitMQ比他们低一个数量级。对于延迟量来说RabbitMQ是最低的。 - 持久化消息比较 ActiveMq 和RabbitMq 都支持。持久化消息主要是指我们机器在不可抗力因素等情况下挂掉了,消息不会丢失的机制。 - 综合技术实现 可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统等等。 - 比较关注的比较, RabbitMQ 和 Kafka RabbitMq 比Kafka 成熟,在可用性上,稳定性上,可靠性上, RabbitMq 胜于 Kafka (理论上)。 另外,Kafka 的定位主要在日志等方面, 因为Kafka 设计的初衷就是处理日志的,可以看做是一个日志(消息)系统一个重要组件,针对性很强,所以 如果业务方面还是建议选择 RabbitMq 。 还有就是,Kafka 的性能(吞吐量、TPS )比RabbitMq 要高出来很多。 |特性| ActiveMQ| RabbitMQ| RocketMQ| Kafka| |-|-|-|-|-| |单机吞吐量| 万级,比 RocketMQ、Kafka 低一个数量级 同 |ActiveMQ| 10 万级,支撑高吞吐 |10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景| |topic 数量对吞吐量的影响 ||| topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic |topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源| |时效性| ms 级| 微秒级,这是 RabbitMQ 的一大特点,延迟最低| ms 级| 延迟在 ms 级以内| |可用性 |高,基于主从架构实现高可用 |同 ActiveMQ |非常高,分布式架构| 非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用| |消息可靠性 |有较低的概率丢失数据|| |经过参数优化配置,可以做到 0 丢失 |同 RocketMQ| |功能支持 |MQ 领域的功能极其完备| 基于 erlang 开发,并发能力很强,性能极好,延时很低| MQ 功能较为完善,还是分布式的,扩展性好| 功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用| 5.如何保证高可用 RabbitMQ 是比较有代表性的,因为是基于主从(非分布式)做高可用性的,我们就以 RabbitMQ 为例子讲解第一种 MQ 的高可用性怎么实现。RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式。 单机模式,就是 Demo 级别的,一般就是你本地启动了玩玩儿的?,没人生产用单机模式 普通集群模式,意思就是在多台机器上启动多个 RabbitMQ 实例,每个机器启动一个。你创建的 queue,只会放在一个 RabbitMQ 实例上,但是每个实例都同步 queue 的元数据(元数据可以认为是 queue 的一些配置信息,通过元数据,可以找到 queue 所在实例)。你消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从 queue 所在实例上拉取数据过来。这方案主要是提高吞吐量的,就是说让集群中多个节点来服务某个 queue 的读写操作。 镜像集群模式:这种模式,才是所谓的 RabbitMQ 的高可用模式。跟普通集群模式不一样的是,在镜像集群模式下,你创建的 queue,无论元数据还是 queue 里的消息都会存在于多个实例上,就是说,每个 RabbitMQ 节点都有这个 queue 的一个完整镜像,包含 queue 的全部数据的意思。然后每次你写消息到 queue 的时候,都会自动把消息同步到多个实例的 queue 上。RabbitMQ 有很好的管理控制台,就是在后台新增一个策略,这个策略是镜像集群模式的策略,指定的时候是可以要求数据同步到所有节点的,也可以要求同步到指定数量的节点,再次创建 queue 的时候,应用这个策略,就会自动将数据同步到其他的节点上去了。这样的话,好处在于,你任何一个机器宕机了,没事儿,其它机器(节点)还包含了这个 queue 的完整数据,别的 consumer 都可以到其它节点上去消费数据。坏处在于,第一,这个性能开销也太大了吧,消息需要同步到所有机器上,导致网络带宽压力和消耗很重!RabbitMQ 一个 queue 的数据都是放在一个节点里的,镜像集群下,也是每个节点都放这个 queue 的完整数据。 6.如何保证消息的可靠性传输啊?要是消息丢失了怎么办啊? 数据的丢失问题,可能出现在生产者、MQ、消费者中 生产者丢失:生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络问题啥的,都有可能。此时可以选择用 RabbitMQ 提供的事务功能,就是生产者发送数据之前开启 RabbitMQ 事务channel.txSelect,然后发送消息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务channel.txRollback,然后重试发送消息;如果收到了消息,那么可以提交事务channel.txCommit。吞吐量会下来,因为太耗性能。所以一般来说,如果你要确保说写 RabbitMQ 的消息别丢,可以开启confirm模式,在生产者那里设置开启confirm模式之后,你每次写的消息都会分配一个唯一的 id,然后如果写入了 RabbitMQ 中,RabbitMQ 会给你回传一个ack消息,告诉你说这个消息 ok 了。如果 RabbitMQ 没能处理这个消息,会回调你一个nack接口,告诉你这个消息接收失败,你可以重试。而且你可以结合这个机制自己在内存里维护每个消息 id 的状态,如果超过一定时间还没接收到这个消息的回调,那么你可以重发。事务机制和cnofirm机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是confirm机制是异步的,你发送个消息之后就可以发送下一个消息,然后那个消息RabbitMQ 接收了之后会异步回调你一个接口通知你这个消息接收到了。所以一般在生产者这块避免数据丢失,都是用confirm机制的。 MQ中丢失:就是 RabbitMQ 自己弄丢了数据,这个你必须开启 RabbitMQ 的持久化,就是消息写入之后会持久化到磁盘,哪怕是 RabbitMQ 自己挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢。设置持久化有两个步骤:创建 queue 的时候将其设置为持久化,这样就可以保证 RabbitMQ 持久化 queue 的元数据,但是不会持久化 queue 里的数据。第二个是发送消息的时候将消息的 deliveryMode 设置为 2,就是将消息设置为持久化的,此时 RabbitMQ 就会将消息持久化到磁盘上去。必须要同时设置这两个持久化才行,RabbitMQ 哪怕是挂了,再次重启,也会从磁盘上重启恢复 queue,恢复这个 queue 里的数据。持久化可以跟生产者那边的confirm机制配合起来,只有消息被持久化到磁盘之后,才会通知生产者ack了,所以哪怕是在持久化到磁盘之前,RabbitMQ 挂了,数据丢了,生产者收不到ack,你也是可以自己重发的。注意,哪怕是你给 RabbitMQ 开启了持久化机制,也有一种可能,就是这个消息写到了 RabbitMQ 中,但是还没来得及持久化到磁盘上,结果不巧,此时 RabbitMQ 挂了,就会导致内存里的一点点数据丢失。 消费端丢失:你消费的时候,刚消费到,还没处理,结果进程挂了,比如重启了,那么就尴尬了,RabbitMQ 认为你都消费了,这数据就丢了。这个时候得用 RabbitMQ 提供的ack机制,简单来说,就是你关闭 RabbitMQ 的自动ack,可以通过一个 api 来调用就行,然后每次你自己代码里确保处理完的时候,再在程序里ack一把。这样的话,如果你还没处理完,不就没有ack?那 RabbitMQ 就认为你还没处理完,这个时候 RabbitMQ 会把这个消费分配给别的 consumer 去处理,消息是不会丢的。  6.如何保证消息顺序性 先看看顺序会错乱的场景:RabbitMQ:一个 queue,多个 consumer,这不明显乱了;  解决  7.如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决? 消息积压处理办法:临时紧急扩容: 先修复 consumer 的问题,确保其恢复消费速度,然后将现有 cnosumer 都停掉。 新建一个 topic,partition 是原来的 10 倍,临时建立好原先 10 倍的 queue 数量。 然后写一个临时的分发数据的 consumer 程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的 10 倍数量的 queue。 接着临时征用 10 倍的机器来部署 consumer,每一批 consumer 消费一个临时 queue 的数据。这种做法相当于是临时将 queue 资源和 consumer 资源扩大 10 倍,以正常的 10 倍速度来消费数据。 等快速消费完积压数据之后,得恢复原先部署的架构,重新用原先的 consumer 机器来消费消息。 8.作为消息队列mq和redis对比 Redis作为消息队列: - 如果你的需求是快产快消的即时消费场景,并且生产的消息立即被消费者消费掉。 - 如果速度是你十分看重的,比如慢了一秒好几千万这种。 - 如果允许出现消息丢失的场景。 - 如果你不需要系统保存你发送过的消息。 - 如果需要处理的数据量并不是那么巨大。 其他消息队列: - 如果你想要稳定的消息队列。 - 如果你想要你发送过的消息可以保留一定的时间,并不是无迹可寻的时候。 - 如果你无法忍受数据的丢失。 - 如果速度不需要那么的快。 - 如果需要处理数据量巨大的时候。 应用场景分析 Redis:轻量级,高并发,延迟敏感 即时数据分析、秒杀计数器、缓存等。 其他MQ:重量级,高并发,异步 批量数据异步处理、并行任务串行化,高负载任务的负载均衡等。 ## mysql ## redis ### 面试相关 #### 1.redis为什么这么快 (一)纯内存操作 (二)单线程操作,避免了频繁的上下文切换 (三)采用了非阻塞I/O多路复用机制 #### 2.redis的数据类型,以及每种数据类型的使用场景 (一)String 这个其实没啥好说的,最常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。 (二)hash 这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果。 (三)list 使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。本人还用一个场景,很合适—取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则。 (四)set 因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。 另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。 (五)sorted set sorted set多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作。 #### 2.什么是Redis? Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库统统加载在内存当中进行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。 因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。 Redis的出色之处不仅仅是性能,Redis最大的魅力是支持保存多种数据结构,此外单个value的最大限制是1GB,不像 memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能。 比方说用他的List来做FIFO双向链表,实现一个轻量级的高性 能消息队列服务,用他的Set可以做高性能的tag系统等等。 另外Redis也可以对存入的Key-Value设置expire时间,因此也可以被当作一 个功能加强版的memcached来用。 Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。 #### 3.Redis是什么意思? Redis代表REmote DIctionary Server。 #### 4.Redis与其他数据库有何不同? Redis是一个NoSQL,Opensource,内存数据结构存储。它遵循键值存储的原则。 它非常快速,持久,可移植,支持多种语言,如C,C ++,C#,Clojure,Common Lisp,D,Dart,Erlang,Go,Haskell,Haxe,Io,Java,JavaScript(Node.js),Julia, Lua,Objective-C,Perl,PHP,纯数据,Python,R,球拍,Ruby,Rust,Scala,Smalltalk和Tcl。 Redis与其他Key-Value存储 键值存储是一种特殊类型的数据库存储系统,其中数据以键和值对的形式存储。 #### 5.使用redis的好处 Redis非常快。 它支持服务器端锁定。 它有一个丰富的客户端库。 这是一个很好的反击。 它支持原子操作。 #### 6.缺点 它是单线程的。 它对一致哈希的客户端支持有限。 它具有很大的持久性开销。 它没有广泛部署。 #### 6.Redis相比memcached有哪些优势? (1) memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类型 (2) redis的速度比memcached快很多 (3) redis可以持久化其数据 #### 一个字符串类型的值能存储最大容量是多少? 512M #### Redis有哪些应用场景 1)会话缓存(Session Cache) 最常用的一种使用Redis的情景是会话缓存(session cache)。用Redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分人都会不高兴的,现在,他们还会这样吗? 幸运的是,随着 Redis 这些年的改进,很容易找到怎么恰当的使用Redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供Redis的插件。 (2)全页缓存(FPC) 除基本的会话token之外,Redis还提供很简便的FPC平台。回到一致性问题,即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。 再次以Magento为例,Magento提供一个插件来使用Redis作为全页缓存后端。 此外,对WordPress的用户来说,Pantheon有一个非常好的插件 wp-redis,这个插件能帮助你以最快速度加载你曾浏览过的页面。 (3)队列 Reids在内存存储引擎领域的一大优点是提供 list 和 set 操作,这使得Redis能作为一个很好的消息队列平台来使用。Redis作为队列使用的操作,就类似于本地程序语言(如Python)对 list 的 push/pop 操作。 如果你快速的在Google中搜索“Redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用Redis创建非常好的后端工具,以满足各种队列需求。例如,Celery有一个后台就是使用Redis作为broker,你可以从这里去查看。 (4)排行榜/计数器 Redis在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis只是正好提供了这两种数据结构。 所以,我们要从排序集合中获取到排名最靠前的10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可: 当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行: ZRANGE user_scores 0 10 WITHSCORES Agora Games就是一个很好的例子,用Ruby实现的,它的排行榜就是使用Redis来存储数据的,你可以在这里看到。 (5)发布/订阅 最后(但肯定不是最不重要的)是Redis的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可作为基于发布/订阅的脚本触发器,甚至用Redis的发布/订阅功能来建立聊天系统! #### Redis如何做内存优化? 尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。 比如你的web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面。 #### redis持久化 Redis的所有数据都是保存在内存中,然后不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”);也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。 由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)。那么这两种持久化方式有什么区别呢,改如何选择呢?网上看了大多数都是介绍这两种方式怎么配置,怎么使用,就是没有介绍二者的区别,在什么应用场景下使用。 RDB:RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。 AOF:AOF持久化以日志的形式记录服务器所处理的每一个写、删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。 配置 ``` RDB持久化配置 Redis会将数据集的快照dump到dump.rdb文件中。此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开6379.conf文件之后,我们搜索save,可以看到下面的配置信息: save 900 1 #在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照。 save 300 10 #在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照。 save 60 10000 #在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。 AOF持久化配置 在Redis的配置文件中存在三种同步方式,它们分别是: appendfsync always #每次有数据修改发生时都会写入AOF文件。 appendfsync everysec #每秒钟同步一次,该策略为AOF的缺省策略。 appendfsync no #从不同步。高效但是数据不会被持久化。 ``` ## apn ### skywalking ## nginx ### nginx架构和原理  Nginx 里有一个 master 进程和多个 worker 进程。master 进程并不处理网络请求,主要负责调度工作进程:加载配置、启动工作进程及非停升级。worker 进程负责处理网络请求与响应。 master进程主要用来管理worker进程,具体包括如下4个主要功能: 接收来自外界的信号。 向各worker进程发送信号。 监控woker进程的运行状态。 当woker进程退出后(异常情况下),会自动重新启动新的woker进程。 woker进程主要用来处理基本的网络事件: 多个worker进程之间是对等且相互独立的,他们同等竞争来自客户端的请求。 一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。 worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致。同时,nginx为了更好的利用多核特性,具有cpu绑定选项,我们可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效。 ### nginx是如何实现高性能的? - 事件驱动模型 基于异步及非阻塞的事件驱动模型,可以说是 Nginx 得以获得高并发、高性能的关键因素。这一点上和 Netty 类似,底层都是使用的 BSD kqueue、Linux epoll 及 Solaris event ports。 - 多进程机制 使用多进程的好处有两点: - 进程之间不共享资源,不需要加锁,减少了使用锁对性能造成的影响,同时降低编程的复杂度,降低开发成本。 - 采用独立的进程,可以让进程互相之间不会影响,如果一个进程发生异常退出时,其它进程正常工作,master 进程则很快启动新的 worker 进程,确保服务不会中断,从而将风险降到最低。 - 内存池 为了避免出现内存碎片,减少向操作系统申请内存的次数、降低各个模块的开发复杂度,Nginx 设计了简单的内存池,它的作用主要是把多次向系统申请内存的操作整合成一次,这大大减少了 CPU 资源的消耗,同时减少了内存碎片。 ### 模块化设计 高度模块化的设计是 Nginx 的架构基础。Openresty 就是在 Nginx 上引入了 lua 等第三方模块,使得扩展更加方便了   ### proxy_pass 1.在nginx中配置proxy_pass代理转发时,如果在proxy_pass后面的url加/,表示绝对根路径;如果没有/,表示相对路径,把匹配的路径部分也给代理走。 ### location 匹配规则和优先级 标识符 描述 location = /uri 精确匹配:用于标准uri前,要求请求字符串和uri严格匹配。如果匹配成功就停止匹配,立即执行该location里面的请求。 location ^~ /uri 开头对URL路径就行前缀匹配,优先级再正则之前 location ~ /uri 正则匹配:用于正则uri前,表示uri里面包含正则,并且区分大小写。 location ~* /uri 正则匹配:用于正则uri前,表示uri里面包含正则,不区分大小写。 location /uri 非正则匹配;用于标准uri前,nginx服务器匹配到前缀最多的uri后就结束,该模式匹配成功后,不会使用正则匹配。 location / 通用匹配,任何未匹配到其他的location的请求都会匹配到 首先精确匹配= 其次是前缀匹配 ^~ 其次是按文件中的顺序的正则匹配 然后匹配不带任何修饰的前缀匹配 最后 / 通用匹配 匹配成功时候停止匹配 ### nginx优化 参考: https://www.cnblogs.com/cheyunhua/p/10670070.html #### nignx运行的工作进程数量 ``` worker_processes 4; ``` #### cpu运行cpu亲和力 比如4核配置: ``` worker_processes 4; worker_cpu_affinity 0001 0010 0100 1000 ``` 比如8核配置: ``` worker_processes 8; worker_cpu_affinity 00000001 00000010 00000100 0000100000010000 00100000 01000000 10000000; ``` worker_processes最多开启8个,8个以上性能提升不会再提升了,而且稳定性变得更低,所以8个进程够用了。 #### nginx最大打开文件数 ``` worker_rlimit_nofile 65535; ``` #### nginx事件处理模型 ``` events { use epoll; worker_connections 65535; multi_accept on; } ``` nginx采用epoll事件模型,处理效率高。 - work_connections是单个worker进程允许客户端最大连接数,这个数值一般根据服务器性能和内存来制定,实际最大值就是worker进程数乘以work_connections。 实际我们填入一个65535,足够了,这些都算并发值,一个网站的并发达到这么大的数量,也算一个大站了! - multi_accept 告诉nginx收到一个新连接通知后接受尽可能多的连接,默认是on,设置为on后,多个worker按串行方式来处理连接,也就是一个连接只有一个worker被唤醒,其他的处于休眠状态,设置为off后,多个worker按并行方式来处理连接,也就是一个连接会唤醒所有的worker,直到连接分配完毕,没有取得连接的继续休眠。当你的服务器连接数不多时,开启这个参数会让负载有一定的降低,但是当服务器的吞吐量很大时,为了效率,可以关闭这个参数。 #### 开启高效传输模式 ``` http { include mime.types; default_type application/octet-stream; …… sendfile on; tcp_nopush on; …… } ``` - Include mime.types : 媒体类型,include 只是一个在当前文件中包含另一个文件内容的指令。 - default_type application/octet-stream :默认媒体类型足够。 - sendfile on:开启高效文件传输模式,sendfile指令指定nginx是否调用sendfile函数来输出文件,对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。 - tcp_nopush on:必须在sendfile开启模式才有效,防止网路阻塞,积极的减少网络报文段的数量(将响应头和正文的开始部分一起发送,而不一个接一个的发送。) #### 连接超时 主要目的是保护服务器资源,CPU,内存,控制连接数,因为建立连接也是需要消耗资源的。 ``` keepalive_timeout 60; tcp_nodelay on; client_header_buffer_size 4k; open_file_cache max=102400 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 1; client_header_timeout 15; client_body_timeout 15; reset_timedout_connection on; send_timeout 15; server_tokens off; client_max_body_size 10m; ``` - keepalived_timeout:客户端连接保持会话超时时间,超过这个时间,服务器断开这个链接。 - tcp_nodelay:也是防止网络阻塞,不过要包涵在keepalived参数才有效。 - client_header_buffer_size 4k:客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过 1k,不过由于一般系统分页都要大于1k,所以这里设置为分页大小。分页大小可以用命令getconf PAGESIZE取得。 - open_file_cache max=102400 inactive=20s :这个将为打开文件指定缓存,默认是没有启用的,max指定缓存数量,建议和打开文件数一致,inactive 是指经过多长时间文件没被请求后删除缓存。 - open_file_cache_valid 30s:这个是指多长时间检查一次缓存的有效信息。 - open_file_cache_min_uses 1 :open_file_cache指令中的inactive 参数时间内文件的最少使用次数,如果超过这个数字,文件描述符一直是在缓存中打开的,如上例,如果有一个文件在inactive 时间内一次没被使用,它将被移除。 - client_header_timeout : 设置请求头的超时时间。我们也可以把这个设置低些,如果超过这个时间没有发送任何数据,nginx将返回request time out的错误。 - client_body_timeout设置请求体的超时时间。我们也可以把这个设置低些,超过这个时间没有发送任何数据,和上面一样的错误提示。 - reset_timeout_connection :告诉nginx关闭不响应的客户端连接。这将会释放那个客户端所占有的内存空间。 - send_timeout :响应客户端超时时间,这个超时时间仅限于两个活动之间的时间,如果超过这个时间,客户端没有任何活动,nginx关闭连接。 - server_tokens :并不会让nginx执行的速度更快,但它可以关闭在错误页面中的nginx版本数字,这样对于安全性是有好处的。 client_max_body_size:上传文件大小限制。 #### fastcgi调优 ``` fastcgi_connect_timeout 600; fastcgi_send_timeout 600; fastcgi_read_timeout 600; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; fastcgi_temp_path/usr/local/nginx1.10/nginx_tmp; fastcgi_intercept_errors on; fastcgi_cache_path/usr/local/nginx1.10/fastcgi_cache levels=1:2 keys_zone=cache_fastcgi:128minactive=1d max_size=10g; ``` - fastcgi_connect_timeout 600 :指定连接到后端FastCGI的超时时间。 - fastcgi_send_timeout 600 :向FastCGI传送请求的超时时间。 - fastcgi_read_timeout 600 :指定接收FastCGI应答的超时时间。 - fastcgi_buffer_size 64k :指定读取FastCGI应答第一部分需要用多大的缓冲区,默认的缓冲区大小为。fastcgi_buffers指令中的每块大小,可以将这个值设置更小。 - fastcgi_buffers 4 64k :指定本地需要用多少和多大的缓冲区来缓冲FastCGI的应答请求,如果一个php脚本所产生的页面大小为256KB,那么会分配4个64KB的缓冲区来缓存,如果页面大小大于256KB,那么大于256KB的部分会缓存到fastcgi_temp_path指定的路径中,但是这并不是好方法,因为内存中的数据处理速度要快于磁盘。一般这个值应该为站点中php脚本所产生的页面大小的中间值,如果站点大部分脚本所产生的页面大小为256KB,那么可以把这个值设置为“8 32K”、“4 64k”等。 - fastcgi_busy_buffers_size 128k :建议设置为fastcgi_buffers的两倍,繁忙时候的buffer。 - fastcgi_temp_file_write_size 128k :在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍,该数值设置小时若负载上来时可能报502BadGateway。 - fastcgi_temp_path :缓存临时目录。 - fastcgi_intercept_errors on :这个指令指定是否传递4xx和5xx错误信息到客户端,或者允许nginx使用error_page处理错误信息。注:静态文件不存在会返回404页面,但是php页面则返回空白页! - fastcgi_cache_path /usr/local/nginx1.10/fastcgi_cachelevels=1:2 keys_zone=cache_fastcgi:128minactive=1d max_size=10g :fastcgi_cache缓存目录,可以设置目录层级,比如1:2会生成16*256个子目录,cache_fastcgi是这个缓存空间的名字,cache是用多少内存(这样热门的内容nginx直接放内存,提高访问速度),inactive表示默认失效时间,如果缓存数据在失效时间内没有被访问,将被删除,max_size表示最多用多少硬盘空间。 - fastcgi_cache cache_fastcgi :#表示开启FastCGI缓存并为其指定一个名称。开启缓存非常有用,可以有效降低CPU的负载,并且防止502的错误放生。cache_fastcgi为proxy_cache_path指令创建的缓存区名称。 - fastcgi_cache_valid 200 302 1h :#用来指定应答代码的缓存时间,实例中的值表示将200和302应答缓存一小时,要和fastcgi_cache配合使用。 - fastcgi_cache_valid 301 1d :将301应答缓存一天。 - fastcgi_cache_valid any 1m :将其他应答缓存为1分钟。 - fastcgi_cache_min_uses 1 :该指令用于设置经过多少次请求的相同URL将被缓存。 - fastcgi_cache_key http://$host$request_uri :该指令用来设置web缓存的Key值,nginx根据Key值md5哈希存储.一般根据$host(域名)、$request_uri(请求的路径)等变量组合成proxy_cache_key 。 - fastcgi_pass :指定FastCGI服务器监听端口与地址,可以是本机或者其它。 总结: nginx的缓存功能有:proxy_cache / fastcgi_cache - proxy_cache的作用是缓存后端服务器的内容,可能是任何内容,包括静态的和动态。 - fastcgi_cache的作用是缓存fastcgi生成的内容,很多情况是php生成的动态的内容。 - proxy_cache缓存减少了nginx与后端通信的次数,节省了传输时间和后端宽带。 - fastcgi_cache缓存减少了nginx与php的通信的次数,更减轻了php和数据库(mysql)的压力。 #### gzip调优 使用gzip压缩功能,可能为我们节约带宽,加快传输速度,有更好的体验,也为我们节约成本,所以说这是一个重点。 Nginx启用压缩功能需要你来ngx_http_gzip_module模块,apache使用的是mod_deflate。 一般我们需要压缩的内容有:文本,js,html,css,对于图片,视频,flash什么的不压缩,同时也要注意,我们使用gzip的功能是需要消耗CPU的! ``` gzip on; gzip_min_length 2k; gzip_buffers 4 32k; gzip_http_version 1.1; gzip_comp_level 6; gzip_typestext/plain text/css text/javascriptapplication/json application/javascript application/x-javascriptapplication/xml; gzip_vary on; gzip_proxied any; gzip on; #开启压缩功能 ``` - gzip_min_length 1k :设置允许压缩的页面最小字节数,页面字节数从header头的Content-Length中获取,默认值是0,不管页面多大都进行压缩,建议设置成大于1K,如果小与1K可能会越压越大。 - gzip_buffers 4 32k :压缩缓冲区大小,表示申请4个单位为32K的内存作为压缩结果流缓存,默认值是申请与原始数据大小相同的内存空间来存储gzip压缩结果。 - gzip_http_version 1.1 :压缩版本,用于设置识别HTTP协议版本,默认是1.1,目前大部分浏览器已经支持GZIP解压,使用默认即可。 - gzip_comp_level 6 :压缩比例,用来指定GZIP压缩比,1压缩比最小,处理速度最快,9压缩比最大,传输速度快,但是处理慢,也比较消耗CPU资源。 - gzip_types text/css text/xml application/javascript :用来指定压缩的类型,‘text/html’类型总是会被压缩。默认值: gzip_types text/html (默认不对js/css文件进行压缩) 压缩类型,匹配MIME型进行压缩; - 不能用通配符 text/*; - text/html默认已经压缩 (无论是否指定); - 设置哪压缩种文本文件可参考 conf/mime.types。 - gzip_vary on :varyheader支持,改选项可以让前端的缓存服务器缓存经过GZIP压缩的页面,例如用Squid缓存经过nginx压缩的数据。 #### expires缓存调优 缓存,主要针对于图片,css,js等元素更改机会比较少的情况下使用,特别是图片,占用带宽大,我们完全可以设置图片在浏览器本地缓存365d,css,js,html可以缓存个10来天,这样用户第一次打开加载慢一点,第二次,就非常快了!缓存的时候,我们需要将需要缓存的拓展名列出来, Expires缓存配置在server字段里面。 ``` location ~* \.(ico|jpe?g|gif|png|bmp|swf|flv)$ { expires 30d; #log_not_found off; access_log off; } location ~* \.(js|css)$ { expires 7d; log_not_found off; access_log off; } ``` 注:log_not_found off;是否在error_log中记录不存在的错误。默认是。 总结: expire功能优点: - expires可以降低网站购买的带宽,节约成本; - 同时提升用户访问体验; - 减轻服务的压力,节约服务器成本,是web服务非常重要的功能。 expire功能缺点: - 被缓存的页面或数据更新了,用户看到的可能还是旧的内容,反而影响用户体验。 解决办法:第一个缩短缓存时间,例如:1天,但不彻底,除非更新频率大于1天;第二个对缓存的对象改名。 网站不希望被缓存的内容: - 网站流量统计工具; - 更新频繁的文件(google的logo)。 #### 防盗链 防止别人直接从你网站引用图片等链接,消耗了你的资源和网络流量,那么我们的解决办法由几种: 水印,品牌宣传,你的带宽,服务器足够; 防火墙,直接控制,前提是你知道IP来源; 防盗链策略下面的方法是直接给予404的错误提示。 ``` location ~*^.+\.(jpg|gif|png|swf|flv|wma|wmv|asf|mp3|mmf|zip|rar)$ { valid_referers noneblocked www.benet.com benet.com; if($invalid_referer) { #return 302 http://www.benet.com/img/nolink.jpg; return 404; break; } access_log off; } ``` 参数可以使如下形式: none :意思是不存在的Referer头(表示空的,也就是直接访问,比如直接在浏览器打开一个图片)。 blocked :意为根据防火墙伪装Referer头,如:“Referer:XXXXXXX”。 server_names :为一个或多个服务器的列表,0.5.33版本以后可以在名称中使用“*”通配符。 #### 内核参数的优化 - fs.file-max = 999999:这个参数表示进程(比如一个worker进程)可以同时打开的最大句柄数,这个参数直线限制最大并发连接数,需根据实际情况配置。 - net.ipv4.tcp_max_tw_buckets = 6000 :这个参数表示操作系统允许TIME_WAIT套接字数量的最大值,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。该参数默认为180000,过多的TIME_WAIT套接字会使Web服务器变慢。注:主动关闭连接的服务端会产生TIME_WAIT状态的连接 - net.ipv4.ip_local_port_range = 1024 65000 :允许系统打开的端口范围。 - net.ipv4.tcp_tw_recycle = 1 :启用timewait快速回收。 - net.ipv4.tcp_tw_reuse = 1 :开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接。这对于服务器来说很有意义,因为服务器上总会有大量TIME-WAIT状态的连接。 - net.ipv4.tcp_keepalive_time = 30:这个参数表示当keepalive启用时,TCP发送keepalive消息的频度。默认是2小时,若将其设置的小一些,可以更快地清理无效的连接。 - net.ipv4.tcp_syncookies = 1 :开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理。 - net.core.somaxconn = 40960 :web 应用中 listen 函数的 backlog 默认会给我们内核参数的。 - net.core.somaxconn :限制到128,而nginx定义的NGX_LISTEN_BACKLOG 默认为511,所以有必要调整这个值。注:对于一个TCP连接,Server与Client需要通过三次握手来建立网络连接.当三次握手成功后,我们可以看到端口的状态由LISTEN转变为ESTABLISHED,接着这条链路上就可以开始传送数据了.每一个处于监听(Listen)状态的端口,都有自己的监听队列.监听队列的长度与如somaxconn参数和使用该端口的程序中listen()函数有关。somaxconn定义了系统中每一个端口最大的监听队列的长度,这是个全局的参数,默认值为128,对于一个经常处理新连接的高负载 web服务环境来说,默认的 128 太小了。大多数环境这个值建议增加到 1024 或者更多。大的侦听队列对防止拒绝服务 DoS 攻击也会有所帮助。 - net.core.netdev_max_backlog = 262144 :每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。 - net.ipv4.tcp_max_syn_backlog = 262144 :这个参数标示TCP三次握手建立阶段接受SYN请求队列的最大长度,默认为1024,将其设置得大一些可以使出现Nginx繁忙来不及accept新连接的情况时,Linux不至于丢失客户端发起的连接请求。 - net.ipv4.tcp_rmem = 10240 87380 12582912 :这个参数定义了TCP接受缓存(用于TCP接受滑动窗口)的最小值、默认值、最大值。 - net.ipv4.tcp_wmem = 10240 87380 12582912:这个参数定义了TCP发送缓存(用于TCP发送滑动窗口)的最小值、默认值、最大值。 - net.core.rmem_default = 6291456:这个参数表示内核套接字接受缓存区默认的大小。 - net.core.wmem_default = 6291456:这个参数表示内核套接字发送缓存区默认的大小。 - net.core.rmem_max = 12582912:这个参数表示内核套接字接受缓存区的最大大小。 - net.core.wmem_max = 12582912:这个参数表示内核套接字发送缓存区的最大大小。 - net.ipv4.tcp_syncookies = 1:该参数与性能无关,用于解决TCP的SYN攻击。 下面贴一个完整的内核优化设置: ``` fs.file-max = 999999 net.ipv4.ip_forward = 0 net.ipv4.conf.default.rp_filter = 1 net.ipv4.conf.default.accept_source_route = 0 kernel.sysrq = 0 kernel.core_uses_pid = 1 net.ipv4.tcp_syncookies = 1 kernel.msgmnb = 65536 kernel.msgmax = 65536 kernel.shmmax = 68719476736 kernel.shmall = 4294967296 net.ipv4.tcp_max_tw_buckets = 6000 net.ipv4.tcp_sack = 1 net.ipv4.tcp_window_scaling = 1 net.ipv4.tcp_rmem = 10240 87380 12582912 net.ipv4.tcp_wmem = 10240 87380 12582912 net.core.wmem_default = 8388608 net.core.rmem_default = 8388608 net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.core.netdev_max_backlog = 262144 net.core.somaxconn = 40960 net.ipv4.tcp_max_orphans = 3276800 net.ipv4.tcp_max_syn_backlog = 262144 net.ipv4.tcp_timestamps = 0 net.ipv4.tcp_synack_retries = 1 net.ipv4.tcp_syn_retries = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_mem = 94500000 915000000 927000000 net.ipv4.tcp_fin_timeout = 1 net.ipv4.tcp_keepalive_time = 30 net.ipv4.ip_local_port_range = 1024 65000 执行sysctl -p使内核修改生效。 ``` ## ansible 1、Ansible是什么? Ansible是一个自动化运维工具,基于Python开发,集合了众多运维工具的优点,可以实现批量系统配置、批量程序部署、批量运行命令等功能。并且它是基于模块工作的,本身没有批量部署的能力,真正批量部署的是ansible所运行的模块,而ansible只是提供一种框架。 2、Ansible常用模块(至少6个)? command ping yum copy service shell file replace user group 3、什么是 Ansible 模块? 模块被认为是 Ansible 的工作单元。每个模块大多是独立的,可以用标准的脚本语言编写,如 Python、Perl、Ruby、bash 等。模块的一个重要属性是幂等性,意味着一个操作执行多次不会产生副作用。 4、什么是 Ansible 的 playbooks ? Playbooks 是 Ansible 的配置、部署和编排语言,它是基于YAML语言编写的。他们可以描述您希望远程系统实施的策略,或者描述一般 IT 流程中的一系列步骤。 5、描述Ansible是如何工作的? Ansible由节点和控制机器组成。 控制机器是安装Ansibles的地方,节点由这些机器通过SSH管理。 借助SSH协议,控制机器可以部署临时存储在远程节点上的模块。 控制机器使用ansible或者ansible-playbooks在服务器终端输入的Ansible命令集或者playbook后,Ansible会遵循预先编排的规则将PLAYbook逐条拆解为Play,再将Play组织成Ansible可以识别的任务tasks,随后调用任务涉及到的所有MODULES及PLUGINS,根据主机清单INVENTORY中定义的主机列表通过SSH协议将任务集以临时文件或者命令的形式传输到远程节点并返回结果,如果是临时文件则执行完毕后自动删除。 ## LDAP ### LDAP的概述 LDAP(Light Directory Access Portocol),它是基于X.500标准的轻量级目录访问协议。 目录是一个为查询、浏览和搜索而优化的数据库,它成树状结构组织数据,类似文件目录一样。 目录数据库和关系数据库不同,它有优异的读性能,但写性能差,并且没有事务处理、回滚等复杂功能,不适于存储修改频繁的数据。所以目录天生是用来查询的,就好象它的名字一样。 LDAP目录服务是由目录数据库和一套访问协议组成的系统。 ### 目录树概念 1. 目录树:在一个目录服务系统中,整个目录信息集可以表示为一个目录信息树,树中的每个节点是一个条目。 2. 条目:每个条目就是一条记录,每个条目有自己的唯一可区别的名称(DN)。 3. 对象类:与某个实体类型对应的一组属性,对象类是可以继承的,这样父类的必须属性也会被继承下来。 4. 属性:描述条目的某个方面的信息,一个属性由一个属性类型和一个或多个属性值组成,属性有必须属性和非必须属性。 ### DC、UID、OU、CN、SN、DN、RDN |关键字|英文全称|含义 |-|-|-| |dc|Domain Component|域名的部分,其格式是将完整的域名分成几部分,如域名为example.com变成dc=example,dc=com(一条记录的所属位置) |uid|User Id|用户ID songtao.xu(一条记录的ID) |ou|Organization Unit|组织单位,组织单位可以包含其他各种对象(包括其他组织单元),如“oa组”(一条记录的所属组织) |cn|Common Name|公共名称,如“Thomas Johansson”(一条记录的名称) |sn|Surname|姓,如“许” |dn|Distinguished Name|“uid=songtao.xu,ou=oa组,dc=example,dc=com”,一条记录的位置(唯一) |rdn|Relative dn|相对辨别名,类似于文件系统中的相对路径,它是与目录树结构无关的部分,如“uid=tom”或“cn= Thomas Johansson”
上一篇:
nginx 面试题总结
下一篇:
k8s架构和原理***
0
赞
139 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册