nginx多站点代理配置

user root;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;#引入配置文件

events {
worker_connections 1024;
}

http {
log_format main ‘$remote_addr – $remote_user [$time_local] “$request” ‘
‘$status $body_bytes_sent “$http_referer” ‘
‘”$http_user_agent” “$http_x_forwarded_for”‘;

access_log /var/log/nginx/access.log main;

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;

include /etc/nginx/mime.types;
default_type application/octet-stream;

# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /usr/share/nginx/html;
index index.php index.html;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

# location / {
# }

location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html$fastcgi_script_name;
include fastcgi_params;
}
error_page 404 /404.html;
location = /40x.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

#server {
#listen 80;
#listen [::]:80;

# server_name www.wordwwwp.com;

# proxy_connect_timeout 300s;
# proxy_send_timeout 300s;
# proxy_read_timeout 300s;
# fastcgi_send_timeout 300s;
# fastcgi_read_timeout 300s;

# location / {
# proxy_pass http://127.0.0.1:8080;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection ‘upgrade’;
# proxy_set_header Host $host;
# proxy_cache_bypass $http_upgrade;
# try_files $uri $uri/ =404;
# }
#}

upstream wordp {#代理到8080端口
server localhost:8080;
}

server {
listen 80;
server_name www.wordp.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://wordp/;#注意点,必须要有最后的‘/’

}
}

upstream bbs {#代理到8081端口
server localhost:8081;
}

server {
listen 80;
server_name www.bbs.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://bbs/;#注意点,必须要有最后的‘/’
}
}

# Settings for a TLS enabled server.
#
# server {
# listen 443 ssl http2 default_server;
# listen [::]:443 ssl http2 default_server;
# server_name _;
# root /usr/share/nginx/html;
#
# ssl_certificate “/etc/pki/nginx/server.crt”;
# ssl_certificate_key “/etc/pki/nginx/private/server.key”;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 10m;
# ssl_ciphers PROFILE=SYSTEM;
# ssl_prefer_server_ciphers on;
#
# # Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
#
# location / {
# }
#
# error_page 404 /404.html;
# location = /40x.html {
# }
#
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }

}

kafka

Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景

Kafka中发布订阅的对象是topic。我们可以为每类数据创建一个topic,把向topic发布消息的客户端称作producer,从topic订阅消息的客户端称作consumer。Producers和consumers可以同时从多个topic读写数据。一个kafka集群由一个或多个broker服务器组成,它负责持久化和备份具体的kafka消息。
  • Broker:Kafka节点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群。
  • Topic:一类消息,消息存放的目录即主题,例如page view日志、click日志等都可以以topic的形式存在,Kafka集群能够同时负责多个topic的分发。
  • Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列
  • Segment:partition物理上由多个segment组成,每个Segment存着message信息
  • Producer : 生产message发送到topic
  • Consumer : 订阅topic消费message, consumer作为一个线程来消费
  • Consumer Group:一个Consumer Group包含多个consumer, 这个是预先在配置文件中配置好的。各个consumer(consumer 线程)可以组成一个组(Consumer group ),partition中的每个message只能被组(Consumer group ) 中的一个consumer(consumer 线程 )消费,如果一个message可以被多个consumer(consumer 线程 ) 消费的话,那么这些consumer必须在不同的组。Kafka不支持一个partition中的message由两个或两个以上的consumer thread来处理, 除非来自不同的consumer group。它不能像AMQ那样可以多个BET作为consumer去处理message,这是因为多个BET去消费一个Queue中的数据的时候,由于要保证不能多个线程拿同一条message,所以就需要行级别悲观所(for update),这就导致了consume的性能下降,吞吐量不够。而kafka为了保证吞吐量,只允许一个consumer线程去访问一个partition。如果觉得效率不高的时候,可以加partition的数量来横向扩展,那么再加新的consumer thread去消费。这样没有锁竞争,充分发挥了横向的扩展性,吞吐量极高。这也就形成了分布式消费的概念
  • 关于如何设置partition值需要考虑的因素。一个partition只能被一个消费者消费(一个消费者可以同时消费多个partition),因此,如果设置的partition的数量小于consumer的数量,就会有消费者消费不到数据。所以,推荐partition的数量一定要大于同时运行的consumer的数量。另外一方面,建议partition的数量大于集群broker的数量,这样leader partition就可以均匀的分布在各个broker中,最终使得集群负载均衡。在Cloudera,每个topic都有上百个partition。需要注意的是,kafka需要为每个partition分配一些内存来缓存消息数据,如果partition数量越大,就要为kafka分配更大的heap space

好处:

解耦

可恢复性

缓冲(生产大于消费时)

灵活性&峰值处理

异步通信

两种模式:

发布订阅(一对多,消费数据之后不会清楚数据,两种:消费者主动拉(缺点:需要维护一个长连接),队列推送(缺点:消费不了,系统崩溃))

点对点(一对一,消费者主动拉取数据,消息收到后清除消息)

角色:

生产者

消费者

消费者组

kafka 高性能的原因:

  1. 采用操作系统层面的页缓存来缓存数据。利用Page Cache空中接力的方式来实现高效读写,操作系统本身有一层缓存,叫做page cache,是在内存里的缓存,我们也可以称之为os cache,意思就是操作系统自己管理的缓存。原理就是Page Cache可以把磁盘中的数据缓存到内存中,把对磁盘的访问改为对内存的访问。page cache中的数据会随着内核中flusher线程的调度以及对sync()/fsync()的调用写回到磁盘,就算进程崩溃,也不用担心数据丢失。另外,如果consumer要消费的消息不在page cache里,才会去磁盘读取,并且会顺便预读出一些相邻的块放入page cache,以方便下一次读取
  2. 日志采用顺序写入以及零拷贝的方式提升io性能。
  3. partition 的水平分区的概念,能够把一个 topic 拆分成多个分区。
  4. 发送端跟消费端都采用并行的方式来生产消费分区中的消息。

对于一个集群中需要吧topic分成多少个分区,主要取决于业务方面需要满足多大的吞吐量,然后通过调整分区以及合理的配置来提高性能。

零拷贝:

  传统的读取文件数据并发送到网络的步骤如下:

  1. 操作系统将数据从磁盘文件中读取到内核空间的页面缓存;
  2. 应用程序将数据从内核空间读入用户空间缓冲区;
  3. 应用程序将读到数据写回内核空间并放入socket缓冲区;
  4. 操作系统将数据从socket缓冲区复制到网卡接口,此时数据才能通过网络发送。
零拷贝:直接让操作系统的cache中的数据发送到网卡后传输给下游的消费者,直接跳过了两次拷贝数据的步骤,Socket缓存中仅仅会拷贝一个描述符过去,不会拷贝数据到Socket缓存

进程间通信IPC inter-process communication

定义:

两个进程或线程之间传送数据或信号的一些技术或方法。每个进程都有自己独立的系统资源,彼此隔离。为了是不同进程之间相互访问资源进行协调工作,才需要进程间通信。

进程通信目的:

数据传输

共享数据

进程控制

进程通信实现方式:

管道,命名管道,消息队列,信号,信号量,共享内存,套接字socket

swoole

高流量,大并发:

1.即时聊天

2.战旗TV

3.虎牙直播(特点:并发量大,长连接,流量大)

4.YY语音

应用:互联网,移动通信,企业软件,云计算,网络游戏,物联网,车联网。

swoole是什么?

1.异步,并行,高性能

2.纯C编写

3.php扩展(重新定义PHP)

swoole能做什么?

1.异步多线程服务器及客户端

2.异步mysql,redis,数据库连接池,任务队列

3.http/websocket服务器/客户端

4.异步文件读写

5.swoole2.0支持协程

 

 

秒杀注意点

注意点

1.脱离原站部署

2.预测,测试,监控

关键点

1.高可用:双活

2.高并发:负载均衡,数据过滤和安全

设计思路

1.静态页面:cdn加速,网址隐藏,页面压缩,缓存机制

2.动态页面:排队,异步,资质抢购

设计分析:

用户:量大,坏人

地域:全国/地区  (cdn加速)

业务流程:前台,后台

设计分层:

第一层:商品展示层

第二层:用户登记层

第三层:数据接入层

第四层:数据处理层

 

 

分析:

第一层:

1.页面优化:图片,js,页面,压缩

2.cdn加速,oss存储

3.隐藏跳转页面:修改js,或修改html代码,双页面

进程是资源分配的基本单位;线程是程序执行的基本单位。

php编程常见的进程和线程

1、在web应用中,我们每次访问PHP,就建立一个PHP进程,当然也会建立至少一个PHP线程。

2、PHP使用pcntl来进行多进程编程

3、PHP中使用pthreads来进行多线程编程

4、nginx的每个进程只有一个线程,每个线程可以处理多个客户端的访问

5、php-fpm使用多进程模型,每个进程只有一个线程,每个线程只能处理一个客户端访问。

6、apache可能使用多进程模型,也可能使用多线程模型,取决于使用哪种SAPI.

内存泄漏和内存溢出

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

内存泄露 memory leak,是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。

memory leak会最终会导致out of memory!

内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。

1.泄漏原因:
一.没有及时释放大变量

二.php-fpm造成的内存泄漏。

三.就是第三方扩展本身实现存在问题

解决办法:

临时办法:查看php-fpm内存占用情况  # ps -ylC php-fpm –sort:rss //按rss排序 直接kill -9 pid号(或cron定时脚本清理)

针对原因一:用完及时销毁变量

针对原因二:配置优化

1.php-fpm.conf中有个参数pm.max_requests,等同于PHP_FCGI_MAX_REQUESTS。意思是一个fpm进程处理多少个请求后自动杀掉另起新进程(默认关闭,开启,适当降低该值)。

2.max_children,这个是每次php-fpm会建立多少个进程,这样实际上的内存消耗是max_children乘以max_requests每个请求使用内存,根据这个我们可以预估一下内存的使用情况,就不用再写脚本去kill了
3.PHP配置文件里面的memory_limit 这个东西,其实,它限制的只是这个“请求处理”的内存。

mysql主从复制和读写分离

一般通过主从复制的方式来同步数据,实现数据安全,再通过读写分离来提升数据库的高并发负载能力。

主从复制:异步复制,半同步复制,同步复制

复制步骤:

1. master在二进制日志记录这些改变,通知存储引擎提交事物。

2. Slave将master的binary log复制到其中的中继日志。

首先从mysql服务器开始一个工作线程I/O线程,I/O线程在master上打开一个普通的连接,然后开始binlog dump process。Binlog dump process从master的二进制日志中读取事件,如果已经跟上master。他会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。

3.Sql线程从中继日志中读取事件,重放其中的事件而更新slave的数据,使其与master的数据一致。

异步复制:MySQL默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。
全同步复制:只当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。
半同步复制:介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。

读写分离:

读写分离就是只在mysql主服务器上写,只在mysql从服务器上读。基本原理是让主数据库处理事务性查询,而从数据库处理select查询。数据库复制被用来把事务性查询导致的变更同步到集群中的数据库。

目前较为常见的mysql读写分离有两种:

1、 基于程序代码的内部实现

在代码中根据select、insert进行路由分类,这类方法也是目前生产环境中较为常用的,优点是性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支;缺点是需要研发人员来实现,运维人员无从下手。

2、 基于中间代理层实现

代理一般位于客户端和服务器之间,代理服务器接收到客户端请求后通过判断后转发到后端数据库。如下有两个常用代理:

Mysql-proxy:其为mysql的开源项目,通过其自带的lua脚本进行sql判断,虽然是mysql官方产品,但是mysql官方并不建议其使用到生产环境中。

Amoeba:由陈思儒开发,该程序由Java语言进行开发。这个软件致力于mysql的分布式数据库前端代理层,它主要为应用层访问mysql的时候充当sql路由功能。Amoeba能够完成多数据源的高可用、负载均衡、数据切片等功能。

提高order by 速度

前提:order by已经使用索引 using index级别,排序类型一致,要么升序要么降序

1.不使用 select *

原因:

(1)当query的字段不是TEXT|BLOB切大小小于max_length_for_sort_data时,会使用单路排序,否者使用双路排序.

(2)数据大小可能超出sort_buffer_size,导致创建临时表合并排序,多次IO

2.提高sort_buffer_size的值

3.提高max_length_sort_data的之