Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringMVC基础

SpringMVC基础

作者头像
用户9645905
发布于 2023-11-19 00:39:39
发布于 2023-11-19 00:39:39
26900
代码可运行
举报
文章被收录于专栏:Linux学习~Linux学习~
运行总次数:0
代码可运行

SpringMVC基础

SpringWebMVC是基于ServletAPI构建的原始Web框架,从⼀开始就包含在Spring框架中。

MVC理论基础

MVC是ModelViewController的缩写,它是软件⼯程中的⼀种软件架构设计模式,它把软件系统分为模型、视图和控制器三个基本部分

  1. View(视图)指在应⽤程序中专⻔⽤来与浏览器进⾏交互,展⽰数据的资源
  2. Model(模型)是应⽤程序的主体部分,⽤来处理程序中数据逻辑的部分
  3. Controller(控制器)可以理解为⼀个分发器,⽤来决定对于视图发来的请求,需要⽤哪⼀个模型来处理,以及处理完后需要跳回到哪⼀个视图,⽤来连接视图和模型

Spring在实现MVC时,也结合⾃⾝项⽬的特点,做了⼀些改变:

学习SpringMVC重点也就是学习如何通过浏览器和⽤⼾程序进⾏交互

主要分以下三个⽅⾯:

  1. 建⽴连接:将⽤⼾/浏览器和Java程序连接起来,也就是访问⼀个地址能够调⽤到我们的Spring程序
  2. 请求:⽤⼾请求的时候会带⼀些参数,在程序中要想办法获取到参数,所以请求这块主要是获取参数的功能
  3. 响应:执⾏了业务逻辑之后,要把程序执⾏的结果返回给⽤⼾,也就是响应

第一个SpringMVC程序

在SpringMVC中使⽤ @RequestMapping 来实现URL路由映射

创建⼀个UserController类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RestController
public class HelloController {
    @ResponseBody
    @RequestMapping("/")
    public String hello() {
        return "Hello,world";
    }
}

效果:

请求

@RequestMapping

@RequestMapping 是⽤来注册接⼝的路由映射的

当⽤⼾访问⼀个URL时,将⽤⼾的请求对应到程序中某个类的某个⽅法的过程就叫路由映射

@RequestMapping即可修饰类,也可以修饰⽅法:

  1. @RequestMapping标识⼀个类:设置映射请求的请求路径的初始信息
  2. @RequestMapping标识⼀个⽅法:设置映射请求请求路径的具体信息
  3. 当修饰类和⽅法时,访问的地址是类路径+⽅法路径

注意:

  1. @RequestMapping 的URL路径也可以是多层路径
  2. @RequestMapping的URL路径最前⾯加不加 / (斜杠)都可以,Spring程序启动时,如果前⾯没有加会拼接上 /
  3. @RequestMapping 既⽀持Get请求,⼜⽀持Post请求,也⽀持其他的请求⽅式

指定GET/POST⽅法类型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping(value = "/getRequest",method= RequestMethod.GET)
@RequestMapping(value = "/postRequest",method= RequestMethod.POST)
传递单参

接收单个参数,在SpringMVC中直接⽤⽅法中的参数就可以

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RestController
public class HelloController {
    @ResponseBody
    @RequestMapping("/")
    public String hello(String name) {
        return "Hello,world"+name;
    }
}

注意:

  1. 使⽤基本类型来接收参数时,参数必须传(除boolean类型),否则会报500错误;类型不匹配时,会报400错误
  2. 对于包装类型,如果不传对应参数,Spring接收到的数据则为null
  3. 对于参数可能为空的数据,建议使⽤包装类型
传递多参

和接收单个参数⼀样,直接使⽤⽅法的参数接收即可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RestController
public class HelloController {
    @ResponseBody
    @RequestMapping("/")
    public String hello(String name,int age) {
        return "Hello,world"+name+age;
    }
}

注意:

前后端进⾏参数匹配时,是以参数的名称进⾏匹配的,因此参数的位置是不影响后端获取参数的结果

传递对象

如果参数⽐较多时,⽅法声明就需要有很多形参,并且后续每次新增⼀个参数,也需要修改⽅法声明,这样不利于代码的维护 可以将这些参数封装为⼀个对象,SpringMVC可以⾃动实现对象参数的赋值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Data
public class Person {
    String name;
    String sex;
    int age;
}
@RestController
public class HelloController {
    @ResponseBody
    @RequestMapping("/")
    public String hello(Person person) {
        return "Hello,world person:"+ person.getName()+person.getAge()+person.getSex();
    }
}

注意:

Spring会根据参数名称⾃动绑定到对象的各个属性上,如果某个属性未传递,则赋值为null(基本类型则赋值为默认初识值,⽐如int类型的属性,会被赋值为0)

传递数组和集合

SpringMVC可以⾃动绑定数组参数的赋值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m2")
public String m2(String[] str) {
    return "Hello,world str:"+ Arrays.toString(str);
}

集合参数:和数组类似,需要使⽤ @RequestParam 绑定参数关系

默认情况下,请求中参数名相同的多个值,是封装到数组;如果要封装到集合,要使⽤@RequestParam 绑定参数关系

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m3")
public String m3(@RequestParam List<String> str) {
    return "Hello,world str:"+ str;
}
传递JSON数据

JSON的语法:

  1. 数据在 键值对(Key/Value) 中
  2. 数据由逗号 , 分隔
  3. 对象⽤ {} 表⽰
  4. 数组⽤ [] 表⽰
  5. 值可以为对象,也可以为数组,数组中可以包含多个对象

JSON优点:

  1. 简单易⽤:语法简单,易于理解和编写,可以快速地进⾏数据交换
  2. 跨平台⽀持:JSON可以被多种编程语⾔解析和⽣成,可以在不同的平台和语⾔之间进⾏数据交换和传输
  3. 轻量级:相较于XML格式,JSON数据格式更加轻量级,传输数据时占⽤带宽较⼩,可以提⾼数据传输速度
  4. 易于扩展:JSON的数据结构灵活,⽀持嵌套对象和数组等复杂的数据结构,便于扩展和使⽤
  5. 安全性:JSON数据格式是⼀种纯⽂本格式,不包含可执⾏代码,不会执⾏恶意代码,因此具有较⾼的安全性

基于以上特点,JSON在Web应⽤程序中被⼴泛使⽤,如前后端数据交互、API接⼝数据传输等

接收JSON对象,需要使⽤ @RequestBody 注解:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m4")
public String m4(@RequestBody Person person) {
    return "Hello,world person:"+ person;
}
@RequestParam

前端传递的参数key和我们后端接收的key可以不⼀致,可以使⽤ @RequestParam 来重命名前后端的参数值,进行构建映射关系

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@ResponseBody
@RequestMapping("/m1")
public String m1(@RequestParam("name") String str) {
    return "Hello,world name:"+ str;
}

注意:

  1. 使⽤ @RequestParam 进⾏参数重命名时,请求参数只能和 @RequestParam 声明的名称⼀致,才能进⾏参数绑定和赋值
  2. 使⽤ @RequestParam 进⾏参数重命名时,参数就变成了必传参数

分析注解:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")//起别名
    String name() default "";

    boolean required() default true;//默认开启必传

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";//默认数值
}

设置非必传参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m1")
public String m1(@RequestParam(value = "name",required = false) String str) {
    return "Hello,world name:"+ str;
}
@PathVariable

pathvariable:路径变量 和字⾯表达的意思⼀样,这个注解主要作⽤在请求URL路径上的数据绑定

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m5/{name}/{id}")
public String m5(@PathVariable Integer id, @PathVariable("name") String username) {
    return "Hello,world person:"+ id+username;
}

如果⽅法参数名称和需要绑定的URL中的变量名称⼀致时,可以简写,不⽤给@PathVariable的属性赋值,否则需要@PathVariable的属性value赋值

@RequestPart

上传⽂件使用@RequestPart 注解

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m6")
public String m6(@RequestPart MultipartFile file) throws IOException {
    String fileName = file.getOriginalFilename();
    file.transferTo(new File("C:\\Users\\HP\\Desktop\\"+fileName));
    return "接收文件名称:"+fileName;
}
Cookie/Session

Cookie和Session的区别:

  1. Cookie是客⼾端保存⽤⼾信息的⼀种机制;Session是服务器端保存⽤⼾信息的⼀种机制
  2. Cookie和Session之间主要是通过SessionId关联起来的;SessionId是Cookie和Session之间的桥梁
  3. Cookie和Session经常会在⼀起配合使⽤,但是不是必须配合 ◦ 完全可以⽤Cookie来保存⼀些数据在客⼾端这些数据不⼀定是⽤⼾⾝份信息,也不⼀定是SessionId ◦ Session中的sessionId也不需要⾮得通过Cookie/Set-Cookie传递,⽐如通过URL传递

传统获取Cookie:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m8")
public String m8(HttpServletRequest request, HttpServletResponse response) {
    Cookie[] cookies = request.getCookies();
    StringBuilder builder = new StringBuilder();
    if(cookies!=null) {
        for (Cookie ck:cookies) {
            builder.append(ck.getName()+":"+ck.getValue());
        }
    }
    return "Cookie:"+builder;
}

简洁获取Cookie:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m8")
public String m9(@CookieValue("test") String test) {
    return "Cookie:"+test;
}

获取Session:

Session是服务器端的机制,我们需要先存储,才能再获取;Session也是基于HttpServletRequest来存储和获取的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m9")
public String m9(HttpServletRequest request) {
    HttpSession session = request.getSession();
    if(session!=null) {
        session.setAttribute("test","hello");
    }
    return "session set";
}
@RequestMapping("/m10")
public String m10(HttpSession session) {
    return "session:"+session.getAttribute("test");
}

说明:

  1. HttpSession getSession(boolean create):参数如果为true,则当不存在会话时新建会话;参数如果为false,则当不存在会话时返回null
  2. HttpSession getSession():和getSession(true)含义⼀样,默认值为true
  3. void setAttribute(Stringname,Objectvalue):使⽤指定的名称绑定⼀个对象到该session会话
  4. ObjectgetAttribute(Stringname):返回在该session会话中具有指定名称的对象,如果没有指定名称的对象,则返回null

简洁获取Session:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/m11")
public String m11(@SessionAttribute(value = "username",required = false) String name) {//获取指定key
    return "session:"+name;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public String m10(HttpSession session) {
    return "session:"+session.getAttribute("test");
}
获取Header

获取Header也是从 HttpServletRequest 中获取

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/param10")
public String param10(HttpServletRequest request, HttpServletResponse response)
    String userAgent = request.getHeader("User-Agent");
	return name + ":"+userAgent;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/header")
public String header(@RequestHeader("User-Agent") String userAgent) {
	return "userAgent:"+userAgent;
}

响应

Http响应结果可以是数据,也可以是静态⻚⾯,也可以针对响应设置状态码,Header信息等

返回静态页面
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        //返回index.html
        return "/index.html";
    }
}

@RestController = @Controller + @ResponseBody

@Controller :定义⼀个控制器,Spring框架启动时加载,把这个对象交给Spring管理

@ResponseBody :定义返回的数据格式为⾮视图,返回⼀个text/html信息

如果想返回视图的话,只需要把 @ResponseBody 去掉就可以了,也就是 @Controller

@ResponseBody

@ResponseBody 表⽰返回数据

@ResponseBody 既是类注解,⼜是⽅法注解:

  1. 如果作⽤在类上,表⽰该类的所有⽅法,返回的都是数据,如果作⽤在⽅法上,表⽰该⽅法返回的是数据
  2. 如果类上有 @RestController 注解时:表⽰所有的⽅法上添加了 @ResponseBody 注解
返回HTML代码⽚段

后端返回数据时,如果数据中有HTML代码,也会被浏览器解析

响应中的Content-Type常⻅取值有以下⼏种:

  1. text/html:body数据格式是HTML
  2. text/css:body数据格式是CSS
  3. application/javascript:body数据格式是JavaScript
  4. application/json:body数据格式是JSON

如果请求的是js⽂件,SpringMVC会⾃动设置Content-Type为 application/javascript

如果请求的是css⽂件,SpringMVC会⾃动设置Content-Type为 text/css

返回JSON

SpringMVC也可以返回JSON,后端⽅法返回结果为对象

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping("/returnJson")
@ResponseBody
public HashMap<String, String> returnJson() {
    HashMap<String, String> map = new HashMap<>();
    map.put("Java", "Java Value");
    map.put("MySQL", "MySQL Value");
    map.put("Redis", "Redis Value");
    return map;
}
设置状态码

SpringMVC会根据我们⽅法的返回结果⾃动设置响应状态码,程序员也可以⼿动指定状态码

通过SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping(value = "/setStatus")
@ResponseBody
public String setStatus(HttpServletResponse response) {
    response.setStatus(401);
    return "设置状态码成功";
}

状态码不影响⻚⾯的展⽰

设置Header

Http响应报头也会向客⼾端传递⼀些附加信息,⽐如服务程序的名称,请求的资源已移动到新地址等,如:Content-Type,Local等

通过 @RequestMapping 注解的属性来实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";
    @AliasFor("path")
    String[] value() default {};
    @AliasFor("value")
    String[] path() default {};
    RequestMethod[] method() default {};
    String[] params() default {};
    String[] headers() default {};
    String[] consumes() default {};
	String[] produces() default {};
}

说明:

  1. value:指定映射的URL
  2. method:指定请求的method类型,如GET,POST等
  3. consumes:指定处理请求(request)的提交内容类型(Content-Type),例如application/json,text/html;
  4. produces:指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回
  5. Params:指定request中必须包含某些参数值时,才让该⽅法处理
  6. headers:指定request中必须包含某些指定的header值,才能让该⽅法处理请求
设置Content-Type

通过设置produces属性的值,设置响应的报头Content-Type

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping(value = "/returnJson2",produces = "application/json")
@ResponseBody
public String returnJson2() {
	return "{\"success\":true}";
}

如果不设置produces,⽅法返回结果为String时,SpringMVC默认返回类型,是text/html

设置响应编码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping(value = "/returnJson2",produces = "application/json;charset=ut
@ResponseBody
public String returnJson2() {
    return "{\"success\":true}";
}
设置其他Header

使⽤SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
response.setHeader("MyHeader","MyHeaderValue");
    return "设置Header成功";
}

设置⼀个带有给定的名称和值的header,如果name已经存在,则覆盖旧的值 返回类型,是text/html

设置响应编码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping(value = "/returnJson2",produces = "application/json;charset=ut
@ResponseBody
public String returnJson2() {
    return "{\"success\":true}";
}
设置其他Header

使⽤SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
response.setHeader("MyHeader","MyHeaderValue");
    return "设置Header成功";
}

设置⼀个带有给定的名称和值的header,如果name已经存在,则覆盖旧的值

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
数据库读写分离架构,为什么我不喜欢
RD:单库数据量太大,数据库扛不住了,我要申请一个数据库从库,读写分离。 DBA:数据量多少? RD:5000w左右。 DBA:读写吞吐量呢? RD:读QPS约200,写QPS约30左右。 上周在公司
架构师之路
2018/02/28
1.9K0
数据库读写分离架构,为什么我不喜欢
1分钟,啥是数据库读写分离架构?
额,数据库读写分离虽然不难,但并不是所有的“数据库扛不住”的场景,都应该用读写分离。今天花1分钟简单介绍下这个场景。
架构师之路
2020/05/28
6890
典型数据库架构设计与实践 | 架构师之路
本文,将介绍数据库架构设计中的一些基本概念,常见问题以及对应解决方案,为了便于读者理解,将以“用户中心”数据库为例,讲解数据库架构设计的常见玩法。 一、用户中心 用户中心是一个常见业务,主要提供用户注册、登录、信息查询与修改的服务,其核心元数据为: User(uid, uname, passwd, sex, age,nickname, …) 其中: uid为用户ID,主键 uname, passwd, sex, age, nickname, …等为用户的属性 数据库设计上,一般来说在业务初期,单库单表就能够
架构师之路
2018/03/02
1.7K0
典型数据库架构设计与实践 | 架构师之路
数据库读写分离这个坑,你应该踩过吧?
每个支付通道支付失败的时候都会返回特定的错误码,业务内部需要将通道特定的错误码转义成内部的错误码,这样对外就可以统一返回我们自己的错误码。
andyxh
2020/12/10
3960
数据库读写分离这个坑,你应该踩过吧?
数据库分库分表解决方案汇总
关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间。
用户4283147
2022/10/27
2.3K0
数据库分库分表解决方案汇总
一文浅谈“读写分离”技术
读写分离,作为一种常用的数据库访问优化手段,得到广泛的应用。本文尝试从读写分离的技术实现、适用场景及典型产品等角度,阐述这一技术的整体现状。
用户5548425
2023/02/16
3.9K0
一文浅谈“读写分离”技术
程序员修神之路--略懂数据库集群读写分离而已
一个可以抵抗高并发流量系统的背后必定有一个高性能的数据库集群,就像每一个成功的男人背后总有一个强势的女人一样。数据库集群在部署模式上属于分布式,但是CAP原则却不适用于分布式数据库,具体原因可见之前文章:、
架构师修行之路
2020/09/14
4180
程序员修神之路--略懂数据库集群读写分离而已
如何搞定数据库水平切分?
本文将介绍数据库架构设计中的一些基本概念,常见问题以及对应解决方案,为了便于读者理解,将以“用户中心”为例,讲解数据库架构设计的常见玩法。
用户1737318
2019/08/29
5980
如何搞定数据库水平切分?
IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议
IM应用从服务端数据的角度来看,它是一种很特殊的应用场景,抛开基础数据、增值业务和附属功能不谈,单从IM聊天工具的立身之本——聊天数据来说,理论上是不需要在服务端存储的(或者说只需要短暂存储——比如离线消息,上线即拉走),这也是为什么微信在前段时间号称绝不存储用户聊天数据的原因(从技术上说这不是没有道理的,但到底有没有存储,这已经超越技术范畴了,不在此文讨论之列 ^_^)。
JackJiang
2018/08/29
1.1K0
为什么我的系统慢?“三大分离”架构上了吗?(5000字长文,收藏)
创业型公司早期讲究快速迭代,随着业务发展,用户量越来越多,系统会开始遇到一些性能瓶颈。“三大分离”架构设计准则,可以在对原有系统改造尽可能小的情况下,快速提升系统性能,是架构师在接手一个“创业型系统”时,最喜欢用的三板斧。
架构师之路
2024/12/24
1420
为什么我的系统慢?“三大分离”架构上了吗?(5000字长文,收藏)
别扯什么CQRS,服务做什么读写分离,就离谱!
1. 一般来说,垂直拆分,是按照“子业务”维度进行拆分,而不是按照“读写”维度进行拆分,这是模块化设计的基本准则;
架构师之路
2025/04/27
3070
别扯什么CQRS,服务做什么读写分离,就离谱!
数据库架构:主备+分库?主从+读写分离?
1、高可用分析:高可用,主库挂了,keepalive(只是一种工具)会自动切换到备库。这个过程对业务层是透明的,无需修改代码或配置。 2、高性能分析:读写都操作主库,很容易产生瓶颈。大部分互联网应用读多写少,读会先成为瓶颈,进而影响写性能。另外,备库只是单纯的备份,资源利用率50%,这点方案二可解决。 3、一致性分析:读写都操作主库,不存在数据一致性问题。 4、扩展性分析:无法通过加从库来扩展读性能,进而提高整体性能。 5、可落地分析:两点影响落地使用。第一,性能一般,这点可以通过建立高效的索引和引入缓存来增加读性能,进而提高性能。这也是通用的方案。第二,扩展性差,这点可以通过分库分表来扩展。
搜云库技术团队
2019/10/17
1.3K0
典型数据库架构设计与实践 | 架构师之路
本文,将介绍数据库架构设计中的一些基本概念,常见问题以及对应解决方案,为了便于读者理解,将以“用户中心”数据库为例,讲解数据库架构设计的常见玩法。
Javen
2018/08/21
6430
典型数据库架构设计与实践 | 架构师之路
数据库典型架构实践
本文将介绍数据库架构设计中的一些基本概念,常见问题以及对应解决方案,为了便于读者理解,将以“用户中心”为例,讲解数据库架构设计的常见玩法。
CSDN技术头条
2019/08/23
5930
关系型数据库的架构演变
在系统初期,整体的并发了相对较小,因此一般都是将所有的数据信息存储在单库中进行读/写操作。但是随着用户规模不断提升,单库逐渐力不从心,TPS/QPS越来越低。因此到了这个时候,dba会将数据库设置为读写分离状态(生产环境一般会采用一主一从或者一主多从),Master负责写操作,Slave作为备库,不开放写操作,但是允许读操作,主从之间保持数据同步即可。 读写分离之后,可以大大提升单库无法支撑的负载压力 需要注意的是:如果Master存在TPS存在较高的情况,Master之前最好将同一份数据落到缓存中,以避免高并发情况下,从Slave中获取不到指定数据的情况发生 [MySQL 主从同步延迟的原因及解决办法(https://blog.csdn.net/soar_away/article/details/72615012)
石臻臻的杂货铺[同名公众号]
2021/07/14
6390
mysql读写分离延迟问题_MySQL读写分离后的延迟解决方案
根据上图可以看到QPS:10.73k,实际上真实的并发大量数据到达的时候,我这里最高的QPS是将近15k.而目前单个数据库分片(实例)4CPU8G内存的配置下,最高的性能是7k的QPS。
全栈程序员站长
2022/09/02
1.4K0
数据库MySQL-读写分离
数据库读写分离对于大型系统或者访问量很高的互联网应用来说,是必不可少的一个重要功能。
cwl_java
2021/08/30
1.4K0
数据库MySQL-读写分离
服务读写分离架构,绝不推荐
缘起 在《服务读写分离(读服务,写服务),是否可行?》中,对背景做了交代,互联网架构设计上,数据库可以读写分离,服务能否读写分离呢? 下面是两种常见的“服务读写分离”架构: 一、单纯服务读写分离 如上
架构师之路
2018/03/02
2.6K0
服务读写分离架构,绝不推荐
当数据库扼住系统性能咽喉,直接分库分表能解决吗?
众所周知,数据库很容易成为应用系统的瓶颈。单机数据库的资源和处理能力有限,在高并发的分布式系统中,可采用分库分表突破单机局限。
lyb-geek
2022/03/10
6840
当数据库扼住系统性能咽喉,直接分库分表能解决吗?
数据库读写分离这个坑,你应该踩过吧?
每个支付通道支付失败的时候都会返回特定的错误码,业务内部需要将通道特定的错误码转义成内部的错误码,这样对外就可以统一返回我们自己的错误码。
huofo
2022/03/18
2120
数据库读写分离这个坑,你应该踩过吧?
推荐阅读
相关推荐
数据库读写分离架构,为什么我不喜欢
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验