nginx负载均衡的几种方式

(1) 轮询

upstream backserver {
      server 192.168.0.1;
      server 192.168.0.2;
}

(2) 加权轮询

upstream backserver {
      server 192.168.0.1 weight=3;
      server 192.168.0.2 weight=7;
}

(3) ip_hash[解决登录态问题]

upstream backserver {
    ip_hash;
    server 192.168.0.1;
    server 192.168.0.2;
}

(4) fair模块[跟踪后端服务器的负载来分发请求]
按后端的响应时间来分配请求,响应时间短的优先分配

upstream backserver {
    server server1;
    server server2;
    fair;
}

(5) check模块[check后端节点检查扩展]
nginx_upstream_check_module (后端服务器健康检测模块)

upstream backserver {
    server server1;
    server server2;
    fair;
    check interval=3000 rise=2 fall=5 timeout=1000 type=http
}

timeout=1000 超时1s即失败
fall=5 检测5次,都失败则标记rs为down
interval=3000 每隔3s检测一次
rise=2 请求2次则标记rs为up
type=http 发送http请求,通过后端的回复包状态来判断后端是否存活

js 的与和或

在js中写出如下的答案 :

var a = 2;

var b = 3;

var andflag = a && b ;

var orflag = a || b;

问andflag 和orflag 分别是什么?

起初我认为: andflag 和orflag 的值都为 true; 毕竟 && 和 || 都是求Boolean ,后来发现,我错了。

答案应该是  andflag  = 3,orflag = 2;

原因是这样的:

在运算过程中,首先js  会将 && 和||  两边的值转成Boolean 类型,然后再算值 ,&&运算如果返回true,则取后面的值,如果|| 返回true,则取前面的值 , 而其中数值转换成boolean 的规则 是:

对象、非零整数、非空字符串返回true,

其它为false   ;

a && b  的运算就是  :因为  a  和  b全是非零整数,所以  a  和  b  也就是true ,而   true && true  返回   true   ,则取后面的b   ,同理  a 和b 全是非零整数,a  和b  全是true  ,则true || true  返回   true ,取|| 前面的值 也就是2;

同样:该逻辑运算符支持短路原则:

如 var  a = “”  ||  null  || 3  ||  4   —->    var a = fasel || false || true ||  true  结果为true  则返回第一个true,即是3
var b = 4 && 5 && null && 0   ——>   var b = true && true && false && false   结果是false   则返回第一个false   即是null .

linux top命令详解

top命令的第一行:

top – 21:31:26 up 15:16, 5 users, load average: 0.61, 0.82, 0.75
依次对应:系统当前时间 up 系统到目前为止运行的时间, 当前登录系统的用户数量,load_average后面的三个数字分别是距离现在一分钟,五分钟,十五分钟的负载情况。这一行的结果与uptime显示信息相同
load average 数据是每隔5s 检查一次活跃的进程数,然后特定算法计算出的数值。如果这个数除以逻辑cpu的数量,结果高于5的时候就表明系统在超负荷运转了。

top 命令的第二行:
Tasks: 240 total,   2 running,  238 sleeping,  0 stopped,  0  zombie依次对应:tasks表示任务(进程),240 total则表示现在有240个进程,其中处于运行中的有2个,238个在休眠(挂起),stopped 状态即停止的进程数为0, zombie状态即僵尸进程数为0

top命令第三行: cpu状态:%Cpu(s): 13.7 us, 1.5 sy, 0.0 ni, 84.2 id, 0.6 wa, 0.0 hi, 0.0 si, 0.0 st
us:user 用户空间占用cpu的百分比sy:system 内核空间占用cpu的百分比ni:niced 改变过优先级的进程占用cpu的百分比空闲cpu百分比wa: IO wait IO等待占用cpu的百分比hi: Hardware IRQ硬中断 占用cpu的百分比si: software软中断 占用cpu的百分比st: 被hypervisor偷去的时间

top命令第四行:内存状态:KB
KiB Mem : 3775264 total, 250100 free, 2495300 used, 1029864 buff/cache

依次对应:物理内存总量(3.7G),空闲内存总量(2.5G),使用中的内存总量(2.4G),缓冲内存量
第四行中使用中的内存总量(used)指的是现在系统内核控制的内存数,空闲内存总量(free)是内核还未纳入其管控范围的数量。纳入内核管理的内存不见得都在使用中,还包括过去使用过的现在可以被重复利用的内存,内核并不把这些可被重新使用的内存交还到free中去,因此在linux上free内存会越来越少,但不用为此担心

对于内存监控,在top里我们要时刻监控第五行swap交换分区的used,如果这个数值在不断的变化,说明内核在不断进行内存和swap的数据交换,这是真正的内存不够用了。

第六行:空行

top第七行,各进程的监控
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

PID — 进程id
USER — 进程所有者
PR — 进程优先级
NI — nice值。负值表示高优先级,正值表示低优先级
VIRT — 进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
RES — 进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
SHR — 共享内存大小,单位kb
S — 进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
%CPU — 上次更新到现在的CPU时间占用百分比
%MEM — 进程使用的物理内存百分比
TIME+ — 进程使用的CPU时间总计,单位1/100秒
COMMAND — 进程名称(命令名/命令行)

常用的有:PID, USR, S, %CPU, %MEM, TIME+, COMMAND
交互命令:h 帮助

敲enter或space , 刷新显示
‘A’:切换交替显示模式top命令视图下,键入‘A’显示如下:

显示4个窗口:
Def (默认字段组)
Job (任务字段组)
Mem (内存字段组)
Usr (用户字段组)四组字段共有一个独立的可配置的概括区域和它自己的可配置任务区域。4个窗口中只有一个窗口是当前窗口。当前窗口的名称显示在左上方。(注:只有当前窗口才会接受你键盘交互命令)
我们可以用’a’和’w’在4个 窗口间切换。’a’移到后一个窗口,’w’移到前一个窗口。用’g’命令你可以输入一个数字来选择当前窗口。在键入‘A‘后在键入‘a‘的显示如下:

多U多核CPU监控

在top基本视图中,按键盘数字“1”,可监控每个逻辑CPU的状况:

观察上图,服务器有4个逻辑CPU,实际上是1个物理CPU。如果不按1,则在top视图里面显示的是所有cpu的平均值。

进程字段排序

默认进入top时,各进程是按照CPU的占用量来排序的,在【top视图 01】中进程ID为14210的java进程排在第一(cpu占用100%),进程ID为14183的java进程排在第二(cpu占用12%)。可通过键盘指令来改变排序字段,比如想监控哪个进程占用MEM最多,我一般的使用方法如下:
1. 敲击键盘“b”(打开/关闭加亮效果),top的视图变化如下:

我们发现进程id为12363的“top”进程被加亮了,top进程就是视图第二行显示的唯一的运行态(runing)的那个进程,可以通过敲击“y”键关闭或打开运行态进程的加亮效果。
高亮运行状态的进程 b, 然后通过y键关闭或打开运行状态进程的加亮效果
2. 敲击键盘“x”(打开/关闭排序列的加亮效果),top的视图变化如下:可以看到,top默认的排序列是“%CPU”。

3. 通过”shift + >”或”shift + <”可以向右或左改变排序列,下图是按一次”shift + >”的效果图:

改变进程显示字段 -- 这个没看懂

1. 敲击“f”键,top进入另一个视图,在这里可以编排基本视图中的显示字段:

这里列出了所有可在top基本视图中显示的进程字段,有”*”并且标注为大写字母的字段是可显示的,没有”*”并且是小写字母的字段是不显示的。如果要在基本视图中显示“CODE”和“DATA”两个字段,可以通过敲击“r”和“s”键

source, sh , bash, ./ 执行脚本的区别

source fileName
作用:在当前bash环境下读取并执行FileName中的命令。该filename文件可以无“执行权限”
注:该命令通常命令“.”来替代
如:source .bash_profile 等价于 . .bash_profile两者等效

sh和bash命令用法sh FileName
bash FileName
作用:在当前bash环境下读取并执行FileName中的命令。该fileName文件可以无“执行权限”
注:两者在执行文件时的不同,是分别用自己的shell来跑文件。
sh使用”-n”选项进行shell脚本的语法检查,使用”-x”选项实现shell脚本逐条语句的跟踪。

./的命令用法./Filename
作用:打开一个子shell来读取并执行FileName中命令。
注:运行一个shell脚本时会启动别一个命令解释器。
每个shell脚本有效地运行在父shell的一个子进程里。这个父shell是指在一个控制终端或在一个xterm窗口中给你命令指示符的进程。


./*.sh 的执行方式等价于 sh ,/*.sh 或 bash ./*.sh, 此三种执行脚本的方式都是重新启动一个子shell,在子shell中执行此脚本
source ./*.sh 和 . ./*.sh的执行方式是等价的,即两种执行方式都是在当前shell进程中执行此脚本,而不是重新启动一个shell 而在子shell进程中执行此脚本。

性能优化方案

  • 减少http请求
  • 压缩js/css
  • 减少cookie大小
  • css放在顶部,js放于底部
  • 避免使用css表达式
  • 使用CDN
  • 使用gzip压缩
  • 配置Etag
  • 加Expires或Cache-control
  • 避免空的src(浏览器在渲染过程中会把src中空内容加载)
  • 使用kv缓存
  • 数据库加索引,选引擎,读写分离,分库分表等
  • php 开启opcache

Redis 支持的数据结构及应用场景

  • string 字符串
  • list 列表
  • set 集合
  • hash 哈希散列
  • zset 有序集合

Redis不同数据结构的应用场景

  • string 最常见,普通的kv存储
  • hash 存储对象,比如存储用户信息,商品信息,订单信息等,(hmset, hgetall, hget等命令)
  • list 每个元素都是string 的双向链表,既队列又栈,可以用于好友列表,粉丝列表,消息队列MQ,最新消息排行(lpush, key value, rpush)
  • set 列表可以存储多个相同的字符串,集合通过散列列表来保证自己存储的每个字符串都各不相同,可用于共同好友,共同兴趣,分类标签,交并差集等运算,集合中成员是唯一的,不能出现重复数据(sadd key value, smembers key)
  • zset 按时间排序的时间轴,排好序的set,每个元素会关联一个分值,redis通过分数来为集合中成员进行从小到大的排序(zadd key score value)

Redis淘汰策略

Redis淘汰策略根据conf配置里的maxmemory_policy决定,我所在的平台maxmemory为10G

  • noeviction(不删除策略,达到最大内存限制时,如果再存,直接返回错误)
  • allkeys-lru 所有key, 优先删除最少使用 (less recently used的key)
  • volatile-lru 只限于设置了expire部分
  • allkeys-random 所有key, 随机删除一部分
  • volatile-random 只限于设置了expire部分,随机删除一部分
  • volatile-ttl 只限于设置了expire部分,优先删除剩余时间短的

淘汰策略选择:

  • 如果数据分冷热, 如果没啥具体的业务特征, 推荐使用allkeys-lru
  • key的访问频率差不多,用allkeys-random,读写所有元素的概率差不多
  • 如果想让Redis根据TTL来筛选删除key, 用volatile-ttl
  • volatile-radom和volatile-random视expire和业务情况而定

Redis的rdb和aof持久化的区别?

RDB持久化:将Redis在内存中的数据库记录定时dump到磁盘上
AOF持久化:将Redis的操作日志以追加的方式写入文件

区别:RDB持久化是指在指定的时间间隔内将内存中数据集快照写入磁盘,实际操作是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储。
AOF持久化以日志形式记录服务器所处理的每一个写删操作,查询操作不会记录,以文本的方式记录

RDB 优点 :

  • 整个Redis数据库只包含一个文件,对于文件备份而言非常完美,一旦系统出现故障,恢复容易,文件迁移方便
  • 性能最大化:持久化是fork子进程,由子进程完成持久化工作,极大的避免服务进程执行IO操作
  • 相比AOF,持久的数据集大时,RDB启动更快

RDB缺点:

  • 如果要保证数据的高可用,最大限度的避免数据丢失,RDB不是最好的,系统在定时持久化之前宕机,数据将丢失
  • RDB通过fork子进程来协助完成数据持久化工作,如果数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至1秒钟

AOF优点:

  • 数据安全性更高,每秒同步,每修改同步(效率低),不同步,每秒同步(异步)效率非常高,一旦宕机,丢失1s
  • 写日志是append模式,写入即使宕机,也不会破坏日志文件中已经存在的内容,redis_check_aof解决数据一致性
  • AOF日志格式清晰,易于理解

AOF缺点:

  • 相同数量的数据集,AOF文件大于RDB文件
  • AOF恢复速度比RDB慢
  • AOF运行效率比RDB慢

总结:

  • 愿意牺牲性能,换取更高的缓存一致性 aof
  • 缓存一致性不用那么高,但是备份性能高 rdb

常见高可用高性能高并发解决

  • html静态化,CMS常用的高并发解决方案,需要注意更新策略
  • 图片服务器分离(分担web 服务器i/o负载,为图片服务器设置针对性的缓存方案,减少带宽成本,提高平台的可扩展性,可随时增加图片服务器,提高图片吐吞能力)
  • 数据库分库分表、库表散列,比如用户表,奇偶分离,不同模块不同的数据库表,物理上也好做隔离
  • 缓存kv,redis、memcache组件的使用
  • 镜像
  • 负载均衡(nginx, haproxy, 硬件F5)
  • CDN
  • 服务降级(保证关键节点上的可用)
  • 限流(通过对并发访问请求进行限速或一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率,则可以拒绝服务、排队或等待,nginx的limit_conn模块,limit_req模块)
  • 集群(服务器集群,组件集群[redis等])
  • 分布式(mfs,codis等)
  • 超时重试
  • 隔离(线程隔离,进程隔离,读写隔离,动静隔离,机房隔离)
  • 主备方式:HA使用比较多的是keepalived,它使主机备机对外提供同一个虚拟IP,客户端通过vip进行数据操作,正常期间主机一直对外服务,宕机后vip自动漂移到备机上
  • 主从方式:一主多从,主从之间进行数据同步,当Master宕机后,通过Paxos, Raft从Slave中选举出新的Master继续对外服务,主机恢复后以slave的身份重新加入,读写分离也是其中一个目的

js apply和call 使用详解

apply()第一个参数是调用apply的函数运行的作用域,第二个参数可以是Array,也可以是arguments对象

call()第一个参数是this的值没有变化,而其余参数都直接传递给函数(也就是逐一列举出来)


如果要传入的是数组或arguments对象,apply会更方便。

apply和call区别在于传递参数的形式不一样,call要逐一传,且不支持arguments对象传入。

apply和call都是立即执行。