Java项目实战——瑞吉外卖Day07(优化篇二)
读写分离
问题分析
Mysql主从复制
介绍
MysSQL主从复制是一个异步的复制过程,底层是基于Mysql数据库自带的二进制日志功能。就是一台或多台AysQL数据库(slave,即从库)从另一台MysQL数据库(master,即主库)进行日志的复制然后再解析日志并应用到自身,最终实现从库的数据和主库的数据保持一致。MySQL主从复制是MysQL数据库自带功能,无需借助第三方工具。
MysQL复制过程分成三步:
- master将改变记录到二进制日志( binary log)
- slave将master的binary log拷贝到它的中继日志(relay log)
- slave重做中继日志中的事件,将改变应用到自己的数据库中
配置-前置条件
提前准备好两台服务器,分别安装Mysql并启动服务成功
- 主库Master 192.168.188.100
- 从库slave 192.168.188.101
注意:克隆的虚拟机需要修改数据库的uuid
配置-主库Master
第一步:修改Mysq1数据库的配置文件/etc/my.cnf
[mysqld] log-bin=mysql-bin #[必须]启用二进制日志 server-id=100 #[必须]服务器唯一ID
第二步:重启Mysql服务
systemctl restart mysqld
第三步:登录Mysql数据库,执行下面SQL
GRANT REPLICATION SLAVE ON *.* to 'xiaoming'@'%' identified by 'Root@123456';
注:上面SQL的作用是创建一个用户xiaoming,密码为Root@123456,并且给xiaoming用户授予REPLICATION SLAVE权限。常用于建立复制时所需要用到的用户权限,也就是slave必须被master授权具有该权限的用户,才能通过该用户复制。
第四步:登录Mysql数据库,执行下面SQL,记录下结果中File和Position的值
show master status;
注:上面SQL的作用是查看Master的状态,执行完此SQL后不要再执行任何操作
配置-从库Slave
第一步:修改Mysq1数据库的配置文件/etc/my.cnf
[mysqld] server-id=101 #[必须]服务器唯一ID
第二步:重启Mysql服务
systemctl restart mysqld
第三步:登录Mysq1数据库,执行下面SQL
change master to master_host='192.168.188.100',master_user='xiaoming',master_password='Root@123456',master_log_file='mysql-bin.000003',master_log_pos=441; start slave;
第四步:登录Mysql数据库,执行下面SQL,查看从数据库的状态show slave status;
读写分离案例
背景
面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。
Sharding-JDBC介绍
Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。
使用Sharding-JDBC可以在程序中轻松的实现数据库读写分离。
- 适用于任何基于JDBC的ORM框架,如: JPA, Hibernate,Mybatis, Spring JDBC Template或直接使用JDBC。
- 支持任何第三方的数据库连接池,如:DBCP,C3PO,BoneCP, Druid, HikariCP等。
- 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92标准的数据库。
入门案例
使用Sharding-JDBC实现读写分离步骤:
1、导入maven坐标
<dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.0.0-RC1</version> </dependency>
2、在配置文件中配置读写分离规则
spring: shardingsphere: datasource: names: master,slave # 主数据源 master: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.188.100:3306/rw?characterEncoding=utf-8 username: root password: 123456 # 从数据源 slave: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.188.101:3306/rw?characterEncoding=utf-8 username: root password: 123456 masterslave: # 读写分离配置 load-balance-algorithm-type: round_robin #轮询 # 最终的数据源名称 name: dataSource # 主库数据源名称 master-data-source-name: master # 从库数据源名称列表,多个逗号分隔 slave-data-source-names: slave props: sql: show: true #开启SQL显示,默认false
3、在配置文件中配置允许bean定义覆盖配置项
spring: main: allow-bean-definition-overriding: true
项目实现读写分离
环境准备(主从复制)
直接使用我们前面在虚拟机中搭建的主从复制的数据库环境即可。
在主库中创建瑞吉外卖项目的业务数据库reggie并导入相关表结构和数据。
代码构造
在项目中加入Sharding-JDBC实现读写分离步骤:
1、导入maven坐标
2、在配置文件中配置读写分离规则
3、在配置文件中配置允许bean定义覆盖配置项
Nginx
Nginx概述
Nginx是一款轻量级的web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx的网站有:百度、京东、新浪、网易、腾讯、淘宝等。
Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler .ru站点(俄文: Paw6nep)开发的,第一个公开版本0.1.e发布于2004年10月4日。
Nginx下载与安装
可以到Nginx官方网站下载Nginx的安装包,地址为: https://nginx.org/en/download.html
安装过程:
1、安装依赖包yum -y install gcc pcre-devel zlib-devel openssl openssl-devel
2、下载Nginx安装包wget https://nginx.org/download/nginx-1.16.1.tar.gz(需要先yum install wget)
3、解压tar -zxvf nginx-1.16.1.tar.gz
4、cd nginx-1.16.1
5、./ configure --prefix=/usr/local/nginx
6、make && make install
Nginx目录结构
安装完Nginx后,我们先来熟悉一下Nginx的目录结构,如下图:
重点目录/文件:
- conf/nginx.conf nginx配置文件
- html
存放静态文件(html、css、Js等) - logs
日志目录,存放日志文件 - sbin/nginx
二进制文件,用于启动、停止Nginx服务
Nginx命令
查看版本
在sbin目录下输入./nginx -v
检查配置文件正确性
在启动Nginx服务之前,可以先检查一下conf/nginx.conf文件配置的是否有错误,命令如下:
./nginx -t
启动和停止
在sbin目录下。
启动Nginx服务使用如下命令:./nginx
停止Nginx服务使用如下命令:./nginx -s stop
启动完成后可以查看Nginx进程:ps -ef | grep nginx
修改运行的进程数目:vim usr/local/nginx/conf/nginx.conf
worker_processes 2;
重新加载配置文件
可以通过修改profile文件配置环境变量,在/
目录下可以直接使用nginx命令
vim etc/profile
PATH=/usr/local/nginx/sbin:$JAVA_HOME/bin:$PATH
使配置文件生效:source /etc/profile
重启Nginx:nginx -s reload
停止Nginx:nginx -s stop
启动Nginx:nginx
Nginx配置文件结构
整体结构介绍
Nginx配置文件(conf/nginx.conf)整体分为三部分:
- 全局块
和Nginx运行相关的全局配置 - events块
和网络连接相关的配置 - http块
代理、缓存、日志记录、虚拟主机配置- http全局块
- Server块
- Server全局块
- location块
注意:http块中可以配置多个Server块,每个Server块中可以配置多个location块。
Nginx具体应用
部署静态资源
Nginx可以作为静态web服务器来部署静态资源。静态资源指在服务端真实存在并且能够直接展示的一些文件,比如常见的html页面、css文件、js文件、图片、视频等资源。
相对于Tomcat,Nginx处理静态资源的能力更加高效,所以在生产环境下,一般都会将静态资源部署到Nginx中。
将静态资源部署到Nginx非常简单,只需要将文件复制到Nginx安装目录下的html目录中即可。
server { listen 80; #监听端口 server_name localhost; #服务器名称 location/{ #匹配客户端请求url root html; #指定静态资源根目录 index index.html; #指定默认首页 }
反向代理
-
正向代理
是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。
正向代理的典型用途是为在防火墙内的局域网客户端提供访问Internet的途径。
正向代理一般是在客户端设置代理服务器,通过代理服务器转发请求,最终访问到目标服务器。
-
反向代理
反向代理服务器位于用户与目标服务器之间,但是对于用户而言,反向代理服务器就相当于目标服务器,即用户直接访问反向代理服务器就可以获得目标服务器的资源,反向代理服务器负责将请求转发给目标服务器。
用户不需要知道目标服务器的地址,也无须在用户端作任何设定。
-
配置反向代理
server { listen 82; server_name localhost; location / { proxy_pass http://192.168.188.101:8080; #反向代理配置 } }
负载均衡
早期的网站流量和业务功能都比较简单,单台服务器就可以满足基本需求,但是随着互联网的发展,业务流量越来越大并且业务逻辑也越来越复杂,单台服务器的性能及单点故障问题就凸显出来了,因此需要多台服务器组成应用集群,进行性能的水平扩展以及避免单点故障出现。
- 应用集群:将同一应用部署到多台机器上,组成应用集群,接收负载均衡器分发的请求,进行业务处理并返回响应数据
- 负载均衡器:将用户请求根据对应的负载均衡算法分发到应用集群中的一台服务器进行处理
配置负载均衡:
修改ngnix.conf
upstream targetserver{ #upstream指令可以定义一组服务器 server 192.168.188.101:8080; server 192.168.188.101:8081; } server { listen 8080; server_name localhost; location / { proxy_pass http://targetserver; } }
负载均衡策略
前后端分离开发
问题分析
- 开发人员同时负责前端和后端代码开发,分工不明确
- 开发效率低
- 前后端代码混合在一个工程中,不便于管理
- 对开发人员要求高,人员招聘困难
前后端分离开发
介绍
前后端分离开发,就是在项目开发过程中,对于前端代码的开发由专门的前端开发人员负责,后端代码则由后端开发人员负责,这样可以做到分工明确、各司其职,提高开发效率,前后端代码并行开发,可以加快项目开发进度。目前,前后端分离开发方式已经被越来越多的公司所采用,成为当前项目开发的主流开发方式。
前后端分离开发后,从工程结构上也会发生变化,即前后端代码不再混合在同一个maven工程中,而是分为前端工程和后端工程。
开发流程
前后端分离开发后,面临一个问题,就是前端开发人员和后端开发人员如何进行配合来共同开发一个项目?可以按照如下流程进行:
接口(API接口) 就是一个http的请求地址,主要就是去定义:请求路径、请求方式、请求参数、响应数据等内容
前端技术栈
开发工具
- Visual Studio Code
- hbuilder
技术框架
- nodejs
- VUE
- ElementUI
- mock
- webpack
Yapi
介绍
YApi是高效、易用、功能强大的api管理平台,旨在为开发、产品、测试人员提供更优雅的接口管理服务。可以帮助开发者轻松创建、发布、维护 API,YApi还为用户提供了优秀的交互体验,开发人员只需利用平台提供的接口数据写入工具以及简单的点击操作就可以实现接口的管理。
YApi让接口开发更简单高效,让接口的管理更具可读性、可维护性,让团队协作更合理。
源码地址: https://github.com/YMFE/yapi
要使用YApi,需要自己进行部署。
使用
使用YApi可以执行下面操作
- 添加项目
- 添加分类
- 添加接口
- 编辑接口
- 查看接口
Swagger
介绍
使用Swagger你只需要按照它的规范去定义接口及接口相关的信息,再通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,以及在线接口调试页面等等。
knife4j是为Java MVC框架集成Swagger生成Api文档的增强解决方案。
使用方式
操作步骤:
1、导入knife4j的maven坐标
<dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>3.0.2</version> </dependency>
2、导入knife4j相关配置类
WebMvcConfig
@Slf4j @Configuration @EnableSwagger2 @EnableKnife4j public class WebMvcConfig extends WebMvcConfigurationSupport { @Bean public Docket createRestApi() { //文档类型 return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.ka.reggie.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("瑞吉外卖") .version("1.0") .description("瑞吉外卖接口文档") .build(); } }
3、设置静态资源,否则接口文档页面无法访问(addResourceHandlers方法)
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
4、在LoginCheckFilter中设置不需要处理的请求路径
String[] urls = new String[]{ "/employee/login", "/employee/logout", "/backend/**", "/front/**", "/common/**", "/user/sendMsg", "/user/login", "/doc.html", "/webjars/**", "/swagger-resources", "/v2/api-docs" };
常用注解
注解 | 说明 |
---|---|
@Api | 用在请求的类上,例如Controller,表示对类的说明 |
@ApiModel | 用在类上,通常是实体类,表示一个返回响应数据的信息 |
@ApiModelProperty | 用在属性上,描述响应类的属性 |
@ApiOperation | 用在请求的方法上,说明方法的用途、作用 |
@ApilmplicitParams | 用在请求的方法上,表示一组参数说明 |
ApilmplicitParam | 用在@ApilmplicitParams注解中,指定一个请求参数的各个方面 |
项目部署
部署架构
部署环境说明
服务器:
-
192.168.138.100(服务器A)
Nginx:部署前端项目、配置反向代理
Mysql:主从复制结构中的主库
Redis:缓存中间件
-
192.168.138.101(服务器B)
jdk:运行Java项目
git:版本控制工具
maven:项目构建工具
jar: Spring Boot项目打成jar包基于内置Tomcat运行
Mysql:主从复制结构中的从库
部署前端项目
第一步:在服务器A中安装Nginx,将课程资料中的dist目录上传到Nginx的html目录下
第二步:修改Nginx配置文件nginx.conf
server{ listen 80; server_name localhost; location /{ root html/dist; index index.html; } location ^~ /api/{ rewrite ^/api/(.*)$ /$1 break; proxy_pass http://192.168.188.101:8080; } error_page 500 502 503 504 /50x.html; location = /50x.html{ root html; } }
部署后端项目
第一步∶在服务器B中安装jdk、git、maven、MySQL,使用git clone命令将git远程仓库的代码克隆下来
第二步:将资料中提供的reggieStart.sh文件上传到服务器B,通过chmod命令设置执行权限
第三步:执行reggieStart.sh脚本文件,自动部署项目