文章目录

  • 读写分离
    • 为什么要读写分离?
    • 如何实现读写分离?
    • 为什么一个主库多个从库?
    • 是否有缺点?
    • 如何解决延迟问题?
    • 具体如何实现?
    • 实现
  • 读写分离与cqrs的区别
  • 动静分离
    • 什么是动静分离
    • 使用nginx实现动静分离
  • 来源

读写分离

为什么要读写分离?

降低数据库服务器的压力

如何实现读写分离?

  1. 一个主库多个从库
  2. 配置主库复制数据到从库

为什么一个主库多个从库?

一般查询多于增删改,这就是我们常说的二八原则,20%操作是增删改,80%操作是查询

是否有缺点?

有延迟

如何解决延迟问题?

比较及时性的数据还是通过主库查询

具体如何实现?

通过发布服务器,主库发布,而从库订阅,从而实现主从库

实现

我们创建了两个Demo数据库,如下:

我们将Demo1作为主数据库,Demo2作为从数据库,接下来用一张动态图演示创建复制发布-订阅(每隔10秒发布一次)。

我们给出Demo1上下文,Demo2和其一样,按照正常做法接下来我们应该在.NET Core Web应用程序中注入Demo1和Demo2上下文,如下:

public class Demo1DbContext : DbContext{public Demo1DbContext(DbContextOptions<Demo1DbContext> options) :base(options){}public DbSet<Blog> Blogs { get; set; }}
public class Demo2DbContext : DbContext{public Demo2DbContext(DbContextOptions<Demo2DbContext> options) :base(options){}public DbSet<Blog> Blogs { get; set; }}
services.AddDbContext<Demo1DbContext>(options =>{options.UseSqlServer("data source=WANGPENG;User Id=sa;Pwd=sa123;initial catalog=Demo1;integrated security=True;");}).AddDbContext<Demo2DbContext>(options =>{options.UseSqlServer("data source=WANGPENG;User Id=sa;Pwd=sa123;initial catalog=Demo2;integrated security=True;");});

然后我们创建Demo控制器,通过Demo1上下文添加数据,Demo2上下文读取数据,如下:

[Route("[controller]")]public class DemoController : Controller{private readonly Demo1DbContext _demo1DbContext;private readonly Demo2DbContext _demo2DbContext;public DemoController(Demo1DbContext demo1DbContext, Demo2DbContext demo2DbContext){_demo1DbContext = demo1DbContext;_demo2DbContext = demo2DbContext;}[HttpGet("index")]public IActionResult Index(){var blogs = _demo2DbContext.Blogs.ToList();return View(blogs);}[HttpGet("create")]public IActionResult CreateDemo1Blog(){var blog = new Blog(){IsDeleted = false,CreatedTime = DateTime.Now,ModifiedTime = DateTime.Now,Name = "demoBlog1",Url = "http://www.cnblogs.com/createmyslef"};_demo1DbContext.Blogs.Add(blog);_demo1DbContext.SaveChanges();return RedirectToAction(nameof(Index));}}

razor页面

@{ViewData["Title"] = "Index";
}@model IEnumerable<EFCore.Blog><div class="panel panel-primary"><div class="panel-heading panel-head">博客列表</div><div class="panel-body"><table class="table" style="margin: 4px"><tr><th>@Html.DisplayNameFor(model => model.Id)</th><th>@Html.DisplayNameFor(model => model.Name)</th><th>@Html.DisplayNameFor(model => model.Url)</th></tr>@if (Model != null){@foreach (var item in Model){<tr><td>@Html.DisplayFor(modelItem => item.Id)</td><td>@Html.DisplayFor(modelItem => item.Name)</td><td>@Html.DisplayFor(modelItem => item.Url)</td></tr>}}</table></div>
</div>


我们看到通过Demo1上下文添加数据后重定向到Demo2上下文查询到的列表页面,到了10秒自动同步到Demo2数据库,通过刷新可以看到数据显示。虽然结果如我们所期望,但是实现的路径却令我们不是那么如意,因为所用实体都是一样的,只是说所连接数据库不一样而已,但是我们需要创建两个不同的上下文实例,很显然这不是最佳实践方式,那么我们如何做才是最佳实践方式呢?接下来我们再来创建一个Demo3数据库,表结构和Demo1、Demo2一致,如下:

接下来我们在.NET Core Web应用程序Demo1、Demo2上下文所在的类库中创建如下扩展方法(方便有同行需要学习,给出Demo项目基本结构)。

public static class ChangeDatabase{public static void ChangeToDemo3Db(this DbContext context){context.Database.GetDbConnection().ConnectionString = "data source=WANGPENG;User Id=sa;Pwd=sa123;initial catalog=Demo3;integrated security=True;";}}

我们暂且不去看为何这样设置,我们只是添加上下文扩展方法,更改连接为Demo3的数据库,然后接下来我们获取博客列表时,调用上述扩展方法,请问:是否可以获取到Demo3的数据或者说是否会抛出异常呢?我们依然通过动态图来进行演示,如下:

一直以来我们认为利用 context.Database.GetDbConnection() 方法可以回到ADO.NET进行查询,但是我们通过实际证明,我们可以设置其他数据库连接从而达到读写分离最佳实践方式,免去再实例化一个上下文。所以对于上述我们配置的Demo1和Demo2上下文,我们大可只需要Demo1上下文即主数据库,对于从数据库进行查询,我们只需在Demo1上下文的基础上更该连接字符串即可,如下:

public static class ChangeDatabase{public static void ChangeToDemo2Db(this DbContext context){context.Database.GetDbConnection().ConnectionString = "data source=WANGPENG;User Id=sa;Pwd=sa123;initial catalog=Demo2;integrated security=True;";}}[HttpGet("index")]public IActionResult Index(){_demo1DbContext.ChangeToDemo2Db();var blogs = _demo1DbContext.Blogs.ToList();return View(blogs);}

接下来问题来了,那么为何更改Demo1上下文连接字符串就能转移到其他数据库查询呢?就是为了解决读写分离免去实例化上下文即Demo2的情况,但是内部是如何实现的呢?因为EF Core内部添加了方法实现IRelationalConnection接口,使得我们可以在已存在的上下文实例上重新设置连接字符串即更换数据库,但是其前提是必须保证当前上下文连接已关闭,也就是说比如我们在同一个事务中利用当前上下文进行更改操作,然后更改连接字符串进行更改操作,最后提交事务,因为在此事务内,当前上下文连接还未关闭,所以再更改连接字符串后进行数据库更改操作,将必定会抛出异常。

读写分离与cqrs的区别

网上也没有特别准确的理解,按我目前的理解为:读写分离的主从同步依靠数据库的定时同步,有延迟。而CQRS则是事件驱动,通过监听变化,实时性较高,配合队列等也可以实现异步达到最终一致性

数据库(七),读写分离到CQRS
CQRS详解

动静分离

什么是动静分离

动静分离是指在web服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提升整个服务访问性能和可维护性。

nginx 的动静分离,指的是由 nginx 将客户端请求进行分类转发,静态资源请求(如html、css、图片等)由静态资源服务器处理,动态资源请求(如 jsp页面、servlet程序等)由 tomcat 服务器处理,tomcat 本身是用来处理动态资源的,同时 tomcat 也能处理静态资源,但是 tomcat 本身处理静态资源的效率并不高,而且还会带来额外的资源开销。利用 nginx 实现动静分离的架构,能够让 tomcat 专注于处理动态资源,静态资源统一由静态资源服务器处理,从而提升整个服务系统的性能 。

使用nginx实现动静分离

案例:
在Windows浏览器中输入 192.168.1.103/jsp/hello.jsp,跳转到提前准备好的 jsp 页面,这个动态资源请求是有tomcat服务器处理的;输入 192.168.1.103/image/pika.jpg,跳转到提前准备好的图片,这个静态资源请求是由 linux 主机处理的;输入 192.168.1.103/page/a.html,跳转到提前准备好的 html 页面,这个静态资源请求是由 linux 主机处理的。

  • (1)准备工作

① 在 linux 根目录下新建 static 目录,并在此目录下分别新建 image 目录和 page 目录,在 image 目录中放入准备好的图片 pika.jpg,在 page 目录中放入准备好的页面 a.html
② 在 tomcat 下的 webapps 目录下 新建 jsp 目录,在 jsp 目录中放入提前准备好的页面 hello.jsp
③ 关闭 linux 系统的防火墙或者开放需要被访问的端口

  • (2)具体配置

① 修改 linux 系统中nginx的配置文件 nginx.conf,默认在 /usr/local/nginx/conf 目录下。
将配置文件中server块的内容修改成如下形式:

② 保存修改并启动 nginx ,在Windows浏览器中输入相应请求地址,测试成功的结果如下所示:

<1> 访问 192.168.1.103/jsp/hello.jsp

<2> 访问 192.168.1.103/image/pika.jpg

<3> 访问 192.168.1.103/page/a.html

来源

【EFCore】.NET Core + EFCore 实现数据读写分离
EntityFramework Core进行读写分离最佳实践方式,了解一下(一)?
如何实现动静分离

【架构设计】读写分离、动静分离相关推荐

  1. Nginx反向代理负载均衡虚拟主机动静分离UrlRewrite防盗链

    文章目录 1. Nginx简介 1.1 Nginx背景 1.2 Nginx的优点 1.3 Nginx的功能特性及常用功能 2.Nginx安装 2.1 下载上传解压 1.2 安装 3.nginx核心概念 ...

  2. Nginx一网打尽:动静分离、压缩、缓存、黑白名单、跨域、高可用、性能优化......

    干货!文章有点长,建议先收藏 引言 一.性能怪兽-Nginx概念深入浅出 二.Nginx环境搭建 三.Nginx反向代理-负载均衡 四.Nginx动静分离 五.Nginx资源压缩 六.Nginx缓冲区 ...

  3. 16. Nginx 动静分离

    文章目录 16. 动静分离 16.1 什么是动静分离 16.2 准备测试资源 16.3 修改 nginx 配置文件 16.4 测试 16. 动静分离 16.1 什么是动静分离 动静分离是指在web服务 ...

  4. Nginx一网打尽:动静分离、压缩、缓存等,想要的这都有

    引言 早期的业务都是基于单体节点部署,由于前期访问流量不大,因此单体结构也可满足需求,但随着业务增长,流量也越来越大,那么最终单台服务器受到的访问压力也会逐步增高.时间一长,单台服务器性能无法跟上业务 ...

  5. 使用nginx实现动静分离

    一.什么是动静分离 动静分离是指在web服务器架构中,将静态页面与动态页面或者静态内容接口和动态内容接口分开不同系统访问的架构设计方法,进而提升整个服务访问性能和可维护性. nginx 的动静分离,指 ...

  6. nginx实现动静分离

    nginx实现动静分离 1. 什么是动静分离 2. nginx反向代理与负载均衡 3. nginx实现负载均衡 4. nginx实现动静分离 1. 什么是动静分离 动静分离主要是通过nginx+PHP ...

  7. nginx动静分离配置_Nginx动静分离

    动静分离   动静分离,就是将JSP.Servlet等动态资源交由Tomcat或其他Web服务器处理,将CSS.js.image等静态资源交由Nginx或其他Http服务器处理,充分发挥各自的优势,减 ...

  8. CentOS 7.3:LAMP 动静分离部署

    前言 之前写过一篇部署LAMP平台的博文:基于centos 7搭建LNMP架构,只是那个是基于同一台服务器部署的,用来做测试网站或者访问量不大的情况下,是可以应付的,那么?如果该web网站访问量特别大 ...

  9. LAMP+haproxy+varnish实现网站访问的动静分离及静态资源缓存

    原文  http://sohudrgon.blog.51cto.com/3088108/1601842 系统架构图: 主机规划列表: 全部的主机: CPU : Intel(R) Core(TM)i5- ...

最新文章

  1. .NET Core的日志[2]:将日志输出到控制台
  2. flaskr 报错及其修改
  3. 一次简单的Java服务性能优化,实现压测 QPS 翻倍
  4. 第一天 :学习node.js
  5. python常用类型的内置函数列表
  6. 996页阿里Android面试真题解析火爆全网,全网首发!
  7. MongoDB文件操作(支持大于4M数据)
  8. 1012 数字分类 (20 分)(C语言实现)
  9. 【转】无服务计算(Serverless Computing)核心知识
  10. 五分钟,手撸一个Spring容器!
  11. 下班约会时来了新需求,咋办?
  12. 关于quick-cocos2d-x
  13. Linux学习笔记---常用shell命令
  14. 基于Ajax提交formdata数据、错误信息展示和局部钩子、全局钩子的校验。
  15. linux虚拟机怎么显示桌面,虚拟机中如何开启Linux的3d特效桌面?
  16. Introduction to CALayers Tutorial
  17. 谈谈基类与子类的this指针(C++)
  18. 正则表达式之位置匹配
  19. steam linux安装目录在哪,Ubuntu 16.04 LTS 64位下安装steam游戏平台
  20. 调试经验——用XML格式定义Excel (.xls格式)文件 (XML Spreadsheet format in Excel)

热门文章

  1. SpringSecurity - 基于 Servlet 的应用程序
  2. Parallel programming constructs in Java;并行程序;Atomicity
  3. 2023年如何在知识管理中构建成功的知识图谱/知识库?
  4. Kubernetes——问题与解决方案
  5. (Nginx和PHP下)URL重写,TP实现URL重写
  6. 处理multipart形式的数据
  7. React Hook
  8. 阿里不遗余力阻击微信 胜算几何? 转载
  9. 消息队列如何使用java,想使用消息队列,先考虑下这些问题!,消息队列如何使用...
  10. mysql中常见的数据库对象