您的位置:首页 > 运维架构 > 网站架构

网站优化

2021-08-19 13:27 976 查看

[TOC]

面对并发是如何优化网站性能的?

每个项目都会随着用户和数据的增长调整架构,来面对未来的问题

随着用户的增加,平台开始变得卡顿,开始了问题排查和优化,下面就和大家聊聊是如何处理的吧。

Nginx

一个网站,核心会分为几部分:前端、后台服务、数据库,服务器。

我们最开始项目是打的jar包 ,一个tomcat支撑不了多少并发,

Tomcat 默认配置的最大请求数是 150,也就是说同时支持 150 个并发,当然了,也可以将其改大。所以只能开始搭建集群。

搭建集群后引入了Nginx做反向代理,负载均衡也解决了,根据不同的服务器的性能做了权重,

果然增加了Nginx,做了负载之后,网站访问快了不少。

但是又迎来了Session共享的问题,我们将用户的会话信息放入redis,session共享搞定。

或者使用IPHash

IPhash对客户端请求的IP进行hash操作,然后根据hash结果将同一个客户端ip的请求分发给同一台服务器进行处理,可以解决session不共享的问题。

接入层搞定了之后,发现论坛模块还是很慢。

慢SQL

开始排查日志,发现了一些SQL处理竟然要大于1S。

根本问题是做了联表查询,关联的表比较多,于是我们开始优化数据库结构,增加了许多冗余字段,

后面只用查询一个表了,从蜗速到现在几乎秒开了。

关于分类

从数据库查询优化到使用静态数据管理,因为几乎不会发生变化。

主从复制、读写分离

接入层的问题解决后,发现项目的压力瓶颈转移到了数据库上面,

开始还是单个数据库,但是读和写都在一个数据库,性能完全不太够用,

于是又用一台服务器开始做主从(吐槽:果然只要有钱,问题就好解决一些了),

MySQL的主从还是比较简单的,几个命令就搭建好了,然后我们使用了sharding jdbc来做读写分离。

写完之后,网站整体的性能都提高了。

mysql配置主从数据库

1.修改主服务器master:

#vi /etc/my.cnf
[mysqld]
log-bin=mysql-bin   //[必须]启用二进制日志
server-id=222      //[必须]服务器唯一ID,默认是1,一般取IP最后一段

2.修改从服务器slave:

   #vi /etc/my.cnf
[mysqld]
log-bin=mysql-bin   //[不是必须]启用二进制日志
server-id=226      //[必须]服务器唯一ID,默认是1,一般取IP最后一段

3.重启两台服务器的mysql

service mysqld restart;

4.在主服务器上建立帐户并授权slave:

#/usr/local/mysql/bin/mysql -uroot -pmttang
mysql>GRANT REPLICATION SLAVE ON *.* to 'mysync'@'%' identified by 'password'; //一般不用root帐号

“%”表示所有客户端都可能连,只要帐号,密码正确,此处可用具体客户端IP代替,如192.168.145.226,加强安全。

5.登录主服务器的mysql,查询master的状态

mysql>show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000004 |      308 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

注:执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化

6.配置从服务器Slave

mysql>change master to master_host='192.168.145.222',master_user='username',master_password='password',
master_log_file='mysql-bin.000004',master_log_pos=308;   //注意不要断开,308数字前后无单引号。
Mysql>start slave;    //启动从服务器复制功能

7.检查从服务器复制功能状态:

mysql> show slave status\G

*************************** 1. row ***************************

Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.2.222  //主服务器地址
Master_User: mysync   //授权帐户名,尽量避免使用root
Master_Port: 3306    //数据库端口,部分版本没有此行
Connect_Retry: 60
Master_Log_File: mysql-bin.000004
Read_Master_Log_Pos: 600     //#同步读取二进制日志的位置,大于等于Exec_Master_Log_Pos
Relay_Log_File: ddte-relay-bin.000003
Relay_Log_Pos: 251
Relay_Master_Log_File: mysql-bin.000004
Slave_IO_Running: Yes    //此状态必须YES
Slave_SQL_Running: Yes     //此状态必须YES
......

注:Slave_IO及Slave_SQL进程必须正常运行,即YES状态,否则都是错误的状态(如:其中一个NO均属错误)。

以上操作过程,主从服务器配置完成。

Sharding-JDBC实现读写分离

技术选型:SpringBoot + Sharding-JDBC + MyBatis

使用Sharding-JDBC配置读写分离,优点在于数据源完全有Sharding托管,写操作自动执行master库,读操作自动执行slave库。不需要程序员在程序中关注这个实现了。

1. 核心jar包

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- sharding -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!--阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.14</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
</dependency>
</dependencies>

2. yml文件配置

spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
datasource:
names:
master,slave
# 主数据源
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_master?characterEncoding=utf-8
username: ****
password: ****
# 从数据源
slave:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_slave?characterEncoding=utf-8
username: ****
password: ****
masterslave:
# 读写分离配置, 用于配置从库负载均衡算法类型,可选值:ROUND_ROBIN(轮询),RANDOM(随机)
load-balance-algorithm-type: round_robin
# 最终的数据源名称
name: dataSource
# 主库数据源名称
master-data-source-name: master
# 从库数据源名称列表,多个逗号分隔
slave-data-source-names: slave
props:
# 开启SQL显示,默认false,在执行SQL时,会打印SQL,并显示执行库的名称
sql:
show: true

问题:读写分离架构中经常出现,那就是读延迟的问题如何解决?

刚插入一条数据,然后马上就要去读取,这个时候有可能会读取不到?

归根到底是因为主节点写入完之后数据是要复制给从节点的,读不到的原因就是说数据还没复制到从节点,你就已经去从节点读取了,肯定读不到。

mysql5.7 的主从复制是多线程了,意味着速度会变快,但是不一定能保证百分百马上读取到,这个问题我们可以有两种方式解决:

  (1)是否立马读取,业务层面妥协,是否操作完之后马上要进行读取

  (2)控制是否直接走主库,对于操作完马上要读出来的,且业务上不能妥协的,我们可以对于这类的读取直接走主库,当然Sharding-JDBC也是考虑到这个问题的存在,所以给我们提供了一个功能,可以让用户在使用的时候指定要不要走主库进行读取。在读取前使用下面的方式进行设置就可以了:

public List<UserInfo> getList() {
// 强制路由主库
HintManager.getInstance().setMasterRouteOnly();
return this.list();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: