使用nginx需要注意的问题

避免使用Nginx时陷入坑

Nginx是一个高性能的Web服务器和反向代理服务器,经常用于部署Web应用程序和服务。然而,当使用Nginx时,不遵循最佳实践和常见的错误可能会导致一些问题,本文将介绍一些关于使用Nginx需要避免的坑。

不要滥用正则表达式

在Nginx配置中,正则表达式是非常重要的组成部分,但是如果在配置文件中滥用正则表达式可能会导致服务性能下降,甚至引发诸如内存泄漏、内存溢出和不必要的CPU使用等问题。在配置文件中避免使用过于复杂的正则表达式,尝试使用更简单的规则来实现相同的结果。

慎重使用rewrite指令

rewrite指令用于将URL重定向到其他URL,但是当使用rewrite时,可能会发生以下问题:

  • 内存泄漏:当Nginx服务器上有大量的URL被重定向时,rewrite指令可能导致内存泄漏,这可能会导致服务器崩溃或需要重启服务器以释放内存。

  • 安全问题:rewrite指令可以允许使用者通过URL来操作服务器。如果没有正确地配置rewrite规则,则可能允许攻击者通过修改请求URL来获取敏感数据或执行恶意代码。

  • 性能:rewrite指令可能会降低Web服务器的性能,因为每次重定向都需要执行一些额外的操作。

因此,当使用rewrite指令时,需要慎重考虑它的启用条件和使用方式。

配置文件语法错误处理

Nginx的配置文件语法相对简单,但是在错误的配置文件中使用无效的语法可能会导致服务器崩溃。为了避免这种情况的发生,应该保存原始配置文件并将更改应用到复制的文件中,以确保在配置过程中保留备份。并且,在做任何更改之前,应该测试和验证配置文件,以确保没有语法错误。

不要在配置文件中硬编码密钥

硬编码密钥可能会导致安全漏洞,因为如果密钥泄露,攻击者可能就能够获得访问敏感信息的权限。为了避免此类问题,应该使用环境变量、密钥管理系统或其他安全的方式将密钥注入配置文件中。

应该启用keepalive连接

keepalive连接可以降低网络延迟,减少TCP连接时间,并提高性能。为了从keepalive连接中获得利益,建议设置一个适当的超时时间,以确保不会浪费服务器资源。

总结

以上是在使用Nginx时需要避免的坑。虽然Nginx是一个高性能的Web服务器和反向代理服务器,但是需要遵循最佳实践和常见的错误可能会导致一些问题。在配置文件中避免使用过于复杂的正则表达式、慎重使用rewrite指令、配置文件语法错误处理、不要在配置文件中硬编码密钥以及启用keepalive连接是最佳实践。

Nginx常用功能

NGINX 常用功能

NGINX 是一款高性能的 Web 服务器和反向代理服务器,常用于构建高性能和可伸缩性的 Web 应用程序。除了作为 Web 服务器和反向代理服务器之外,NGINX 还可以实现许多其他功能。在本文中,我们将介绍 NGINX 的一些常用功能。

静态文件服务

NGINX 可以提供静态文件服务,通过 HTTP 协议将本地存储的文件发送到客户端。其实现非常简单,只需要在 NGINX 的配置文件中增加一条 location 指令即可:

1
2
3
4
5
6
7
8
9
server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}

在上述配置中,NGINX 将会监听 80 端口,在根 / 路径下提供静态文件服务。所有访问该路径下的文件请求都将被定位到 /usr/share/nginx/html 文件夹下。

反向代理

NGINX 可以作为反向代理服务器,转发来自客户端的请求到后端的多个 Web 服务器。在这种情况下,NGINX 将作为客户端和后端服务器之间的“中间人”,负责转发请求和响应。其实现也非常简单,只需要在 NGINX 的配置文件中增加一条 server 指令即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
listen 80;
server_name example.com;

location / {
proxy_pass http://backend;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

# ...
}

upstream backend {
server backend1.example.com;
server backend2.example.com;
}

在上述配置中,NGINX 将会监听 80 端口,在 example.com 的根路径下转发所有请求到名为 backend 的后端服务器。后端服务器的地址应该在 upstream 块中定义。同时,NGINX 还可以设置一些代理相关的头部信息。

负载均衡

NGINX 可以作为负载均衡器,将来自客户端的请求分发到多个后端服务器,并尽可能地平均负载。在这种情况下,NGINX 将作为客户端和后端服务器之间的“中间人”,负责分发请求和响应。其实现也非常简单,只需要在 NGINX 的配置文件中增加一条 upstream 指令即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
upstream backend {
server backend1.example.com;
server backend2.example.com;
server backend3.example.com;
}

server {
listen 80;

location / {
proxy_pass http://backend;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
}

在上述配置中,NGINX 将会监听 80 端口,并将来自客户端的请求分发到三个名为 backend1.example.combackend2.example.combackend3.example.com 的后端服务器上。同时,NGINX 还可以设置一些负载均衡相关的选项。

URL 重写

NGINX 可以重写客户端请求的 URL,将原始 URL 转换为另一个 URL 并发送到后端服务器。这种功能可用于隐藏后端服务器的实际位置、根据请求内容转发到不同的后端服务器、或调整请求的结构等。其实现需要在 NGINX 的配置文件中增加一条 location 指令:

1
2
3
location / {
rewrite ^/(.*)$ /index.php?q=$1 last;
}

在上述配置中,NGINX 将会重写客户端请求的 URL,在路径 / 下将所有请求重写为 /index.php?q=$1 的格式。其中,$1 是原始 URL 的捕获组。

SSL 终端

NGINX 可以作为 SSL 终端,与客户端建立 SSL 连接,然后解密和加密所有传输的数据。其实现需要在 NGINX 的配置文件中增加一条 server 指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 443 ssl;
server_name example.com;

ssl_certificate /path/to/certificate.pem;
ssl_certificate_key /path/to/certificate_key.pem;

location / {
proxy_pass http://backend;
proxy_redirect off;
}

# ...
}

在上述配置中,NGINX 将会监听 443 端口,并在建立 SSL 连接后将请求分发到名为 backend 的后端服务器上。同时,NGINX 还需要指定 SSL 证书和私钥。

WebSocket 支持

NGINX 可以支持 WebSocket 协议,允许客户端与服务器之间建立双向的实时通信连接。其实现需要在 NGINX 的配置文件中增加一条 location 指令:

1
2
3
4
5
6
7
location /ws {
proxy_pass http://backend;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

在上述配置中,NGINX 将会将路径 /ws 下的所有 WebSocket 请求转发到名为 backend 的后端服务器上。同时,NGINX 还需要设置一些代理相关的头部信息。

缓存

NGINX 可以缓存某些请求的响应,避免反复从后端服务器重新获取响应。其实现需要在 NGINX 的配置文件中增加一条 proxy_cache_path 指令和一条 proxy_cache 指令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m;

server {
# ...

location / {
proxy_cache_bypass $http_pragma;
proxy_cache_revalidate on;
proxy_cache_key "$scheme$request_method$host$request_uri";
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;

proxy_pass http://backend;
}
}

在上述配置中,NGINX 将会缓存名为 my_cache 的反向代理响应。所有请求的缓存将会被存储在 /var/cache/nginx 目录下。同时,NGINX 还可以设置一些缓存相关的选项。

总结

在本文中,我们介绍了 NGINX 的一些常用功能,包括静态文件服务、反向代理、负载均衡、URL 重写、SSL 终端、WebSocket 支持和缓存。这些功能可以用于构建高性能和可伸缩性的 Web对不起啦,脑子转不过啦,暂时无法回答的您的问题,请稍后重试!!

MySQL调优思路

MySQL调优思路

MySQL是一种开源、关系型数据库。调优MySQL是提高系统性能的一个关键部分。本文将介绍一些常见的MySQL调优思路和技巧。

确定瓶颈

要调优MySQL,首先需要确定瓶颈所在。常见的瓶颈包括CPU、内存、磁盘和网络。了解这些瓶颈所在,可以有针对性地优化MySQL。

选择合适的存储引擎

MySQL支持多种不同的存储引擎。不同的存储引擎有不同的优势和劣势。InnoDB是MySQL的默认存储引擎,它适用于事务处理。MyISAM是另一种常见的存储引擎,适用于读取频繁、写入不频繁的应用。选择合适的存储引擎可以提高MySQL的性能。

优化查询语句

优化查询语句可以提高MySQL的性能。在设计查询语句时,需要考虑以下几个方面:

  • 避免使用SELECT *
  • 遵循查询的原则
  • 避免使用子查询
  • 避免使用表连接(尤其是多表连接)
  • 使用索引进行查询

设置合适的缓冲区大小

适当地设置缓冲区大小可以提高MySQL的性能。MySQL中有一些缓冲区,如查询缓存、表缓存、连接缓存和排序缓存等。适当地设置这些缓冲区的大小,可以避免频繁访问磁盘,从而提高MySQL的性能。

使用分区表

如果有大量的数据需要操作,使用分区表可以提高MySQL的性能。分区表将数据分成多个部分,每个部分可以单独进行操作,从而提高操作效率。

使用主从复制

使用主从复制可以提高MySQL的性能和可用性。主从复制是将主数据库中的数据复制到从数据库中,从数据库可以用于读取操作,从而减轻主数据库的负载。

定期维护数据库

定期进行数据库的维护可以提高MySQL的性能。维护工作包括备份数据库、优化数据库结构、删除不需要的数据和优化数据库配置等。

以上是MySQL调优的一些常见思路和技巧。通过合理调优MySQL,可以提高性能和可用性,从而更好地满足业务需求。

mysql的分库分表实践

MySQL分库分表实践

概述

MySQL是目前应用最广泛的关系型数据库之一,随着数据量的增长和系统访问的增加,单一的MySQL实例可能无法承受大量的访问和数据存储压力,分库分表成为MySQL扩容的一个最佳实践方案,本文将介绍如何实现MySQL分库分表。

分库分表架构

分库分表架构本质上就是将一个大的数据库拆分为多个数据库实例,然后将每个实例再拆分为多个数据表,最后将访问各个表的业务逻辑分别分配到多个数据库实例上。分库分表的目的在于提高MySQL的性能和扩展能力,降低单机MySQL对系统的压力。

分库分表的最终目的是能够处理海量数据的查询请求,因此我们必须保证分库分表的策略是正确和有效的。一个好的分库分表策略不仅能够大幅度提高MySQL的性能,还能在一定程度上提高MySQL的可用性和可靠性。

常见的MySQL分库分表策略包括:

  • 垂直拆分:将数据库中的不同表按照逻辑功能拆分为不同的数据库实例,这种方法一般用于不同表之间没有关联关系或者关联关系不太紧密的情况。
  • 水平拆分:将数据库中的同一张表按照一定的规则拆分为多个表,每个表存储一部分数据,这种方法一般用于数据存储量非常大的情况。
  • 分区:将同一张表按照一定的规则拆分为若干个子表,每个子表存储一部分数据,这种方法一般用于数据存储量非常大并且查询请求比较频繁的情况。

实践步骤

步骤一:确定业务需求和分库分表策略

在Java代码中使用分库分表的方式有很多,比如使用Sharding-JDBC、MyCAT等中间件,分别在代码层面和数据层面实现分库分表的功能。在使用这些中间件之前,我们需要先确定业务需求和分库分表的策略,包括数据库的切分规则、表的切分规则、数据量以及各种数据操作的约束等。

步骤二:设计分库分表方案

在确定业务需求和分库分表的策略之后,我们需要设计分库分表的方案,包括如何切分数据库、如何切分表、如何在各个数据库实例之间实现数据的同步等。

步骤三:实现数据源的配置和使用

在设计好分库分表方案之后,我们需要在代码中实现数据源的配置和使用。在Java中常使用spring-jdbc和spring-mybatis等框架对分库分表进行实现,通过在配置文件中配置数据源和MyBatis的Mapper接口等信息,我们可以轻松地使用分表查询和分表插入等操作。

步骤四:测试和优化

在实现分库分表系统之后,我们需要对系统进行测试和优化。针对不同业务场景下的数据操作,我们需要评估查询效率、数据写入效率、系统稳定性以及数据一致性等方面的性能。

总结

MySQL分库分表是提高系统性能和扩展能力的一个最佳方案,设计好分库分表的方案并正确地应用在实际场景中,可以极大地提高系统的性能和扩展能力。希望本文能够为大家使用MySQL分库分表提供一些实践经验和思路,让大家更好地应用MySQL分库分表技术。

MySQL规范

MySQL 使用规范

索引规范

  1. 在表中使用索引来加速数据查询和服务,但不要过度使用,因为索引需要占用磁盘空间和计算资源。
  2. 选择唯一索引或组合索引来提高查询效率和减少冗余数据。在执行操作时注意索引的效率和复杂性,并避免竞争条件。
  3. 对于数据类型为字符串的列,应该在其前面定义一个前缀索引,避免不必要的空间占用和计算开销。

SQL 规范

  1. 对于任何 SQL 查询操作,都应该使用合适的语法和正确的顺序来避免错误和提高执行效率。
  2. 对于 SELECT 语句,在使用通配符时应该尽量避免使用 SELECT *,而是在需要的列上明确指明。
  3. 在使用计数函数 COUNT() 时,应该使用 COUNT(*) 而不是 COUNT(column) 来避免空值的统计问题。
  4. 对于 UPDATE 和 DELETE 操作,在对数据表做出重大更改之前应该先备份原有数据,以防止被错误操作所破坏。

命名规范

  1. 对于数据库和表,应该使用下划线作为单词之间的分隔符,如 “my_database” 和 “my_table”。
  2. 对于字段名,应该使用下划线或者驼峰命名方式,如 “my_field_name” 或 “myFieldName”。
  3. 对于存储过程或视图,应该使用有意义的名称来描述它们的功能和用途,以方便管理和维护。
  4. 对于索引,应该使用有意义的名称来反映它们的内容和作用,避免混淆和重复。

以上是 MySQL 使用规范的一些要点,遵循这些规范可以提高数据库的可读性、可维护性和性能。

JDBC驱动

驱动

Mysql的驱动jar, 默认有两个功能, 主从分离和HA.
如果你只是需要一个主从分离, failover功能, 不要sharding, 一个驱动就够,也就不需要引入中间层.

有个Replication协议, 在5.1.x版本之后,增加了这些功能, 以用来支持”multi-host”集群拓扑的访问范式. 这个功能是在驱动层实现的.

jdbc连接如下

1
jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8

通过协议改造后的jdbc连接如下

1
jdbc:mysql:replication://127.0.0.1:3306,127.0.0.1:3307,127.0.0.1:3308/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=false&loadBalanceStrategy=random

协议后的第一个连接, 表示主库Master
后面一堆连接,表示从库Slave, 当然可以有多个
当你把Master的连接也放在后面的一堆里面, 那么它也拥有”读库”的属性了
后面有一堆参数, 来控制这所有连接, 到底要如何相处

代码层

对于Spring来说, 就可以使用Transaction注解来控制这个属性, 一个事务不可能跨两个连接, 所以是读还是写, 由最高层决定.

1
2
3
4
5
public interface UserManager{
public UserDO get(int id);
public void insert(UserDo user);
public void update(int id);
}
1
2
3
4
5
6
7
8
9
10
@Component
public class UserManagerImpl implements UserManager{
@Autowired
private UserDao userDao;
//...
@Transactional(readOnly = false, propagation=Propagation.REQUIRED)
public void insert(UserDO user){
this.userDao.insert(user);
}
}

参数

ppnHKbD.png

  • readFromMasterWhenNoSlaves当所有的salve死掉后, 此参数用来控制主库师傅参与读
  • loadBanlanceStrategy策略用来指定从库的轮询规则. 有轮询, 也有权重, 也可用指定具体策略实现. 当你维护或迁移某个实例时, 先置空流量, 这回非常有用. 或许, 你会给某个DB一个预热的可能.
  • allowMasterDownConnections如果主机宕机,当连接池获取新的连接时会失败.
  • retriesAllDown 当所有的hosts都无法连接时重试的最大次数(依次循环重试),默认为120.
  • autoReconnect 实例既然有下线、就有上线。上线以后要能够继续服务,此参数用来控制断线情况下自动重连而不抛出异常.

linux进程调度算法

当发生下面几种情况的时候会调用短程调度器,然后就看下次执行那个进程啦

时钟中断
I/O中断
操作系统调用
信号(如信号量)


进程调度算法:
    先来先服务(FCFS)
    短作业优先(SPN)
    最短剩余时间(SRT)
    时间片轮转
    最高响应比优先
    公平共享调度


先来先服务
阅读更多

2018年

2018

The most boring thing.

加班!加班!加班!

The most interesting thing.

  • 周六加班
  • 周日加班
  • 节假日加班
  • 365天天加班

Experiences of 2018

温水煮青蛙

Expectations for 2019

跳出去瞜两眼