我踩过的Alwayson的坑!

最近被sql server Alwayson高可用组和读写分离,弄得神魂颠倒,身心俱疲。遇到了下面一些问题,提醒自己也给后来人做些记录。

EntityFramework支不支持Alwayson?

起因:

因为要进行数据库的优化,所以想在现有的sql server基础上采用微软的Alwayson解决方案,实现读写分离把数据库的压力减小一下。

之前两篇文章关于Alwayson的都是建立在直接使用Ado.net的基础上,因为EF也是基于Ado.net的orm所以,我认为也是支持Alwayson的。

写一个测试程序吧:

代码很简单,我就省略了注释,数据库有三个字段如下:

USE [test]
GO

/****** Object:  Table [dbo].[test1]    Script Date: 2016/05/23 10:43:41 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[test1](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [name] [datetime] NULL,
    [test_id] [int] NULL,
 CONSTRAINT [PK_test1] PRIMARY KEY CLUSTERED
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
        private void button1_Click(object sender, EventArgs e)
        {
            using (testEntities dbcontext = new testEntities())
            {
                try
                {

                    var list = (from info in dbcontext.test1
                                select info).ToList();

                    dataGridView1.DataSource = list;
                }
               catch (Exception ex)
                {
                    //do nothing
                }

            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            var count = Convert.ToInt32(textBox1.Text);
            using (testEntities dbcontext = new testEntities())
            {
                for(var i = 1 ; i <= count;i++)
                {
                    test1 t = new test1()
                    {
                        name = System.DateTime.Now,
                        test_id = i
                    };

                    dbcontext.test1.Add(t);
                }
                dbcontext.SaveChanges();
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            using (testEntities dbcontext = new testEntities())
            {
                var item = dbcontext.test1.Where(p => p.id != 0);

                dbcontext.test1.RemoveRange(item);

                dbcontext.SaveChanges();

            }
        }

环境简介:

1.主副本:193.160.26.28

2.辅助副本:193.160.26.32

3.侦听器:193.160.26.30

4.客户端:10.167.218.27

DB First方式连接字符串:(怎么做可以自行查询)

①不进行读写分离的时候

连接字符串如下:

 <connectionStrings>
   <add name="testEntities"
     connectionString="metadata=res://*/test.csdl|res://*/test.ssdl|res://*/test.msl;provider=System.Data.SqlClient;provider connection string=&quot;data sou     rce=tcp:193.160.26.30,1433;initial catalog=test;persist security info=True;user id=sa;password=123456;&quot;" providerName="System.Data.EntityClient"/>
  </connectionStrings>

期待结果:可以读,可以写,并且都是在主副本上进行的。

实际结果:

上图说明,不使用只读的时候,和我们的期待结果一致。

2.采用只读路由

修改连接字符串如下:

<connectionStrings>
<add name="testEntities" connectionString="metadata=res://*/test.csdl|res://*/test.ssdl|res://*/test.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=tcp:193.160.26.30,1433;initial catalog=test;persist security info=True;user id=sa;password=123456;ApplicationIntent=ReadOnly;MultiSubnetFailover=True&quot;" providerName="System.Data.EntityClient"/>
</connectionStrings>

期待结果:能读取(辅助副本),不能写入(因为设定了只读)

实际结果:读取和写入的时候出现了如下的错误:

如上图所示:

在建立与服务器的连接时出错。 在连接到 SQL Server 时,在默认的设置下 SQL Server 不允许远程连接可能会导致此失败。(访问接口: TCP 访问接口,错误: 0 - 无法识别这种主机)(.Net SqlClient 数据访问接口)

为什么呢?

I.最先猜想到的是sql Client的问题,是不是不支持ReadOnly,查了一下msdn,上面解释如下:

https://msdn.microsoft.com/zh-cn/library/system.data.sqlclient(v=vs.110).aspx  意思就是4.0以上版本是支持 ApplicationIntent 的值。可能的值为 ReadWrite 和 ReadOnly

查看一下:目前使用的sql Client,是支持的。

II.不是sqlClinet的问题,又仔细看了一下错误的,host不能识别,考虑是不是DNS的问题,在客户端使用cmd中的ping命令,ping一下侦听器地址

在主副本或者辅助副本中ping一下:

感觉好像是DNS的问题:把程序拷贝到主副本或者辅助副本中执行:

结果:

读过程:

读过程没出现问题。

写过程:出现了只读异常,貌似和我的期待结果一样。

分析问题:

因为我的客户端和两天虚拟机从属于不同的域账户,所以这可能就是问题的点。

解决问题:

怎么才能解决呢?

第一个方法:把客户端加到和虚拟机同一个域当中,但是这样做是很有风险的,不能保证每一个客户端都和服务器在同一个域当中。所以我不能采用这样的方式

第二个方法:仔细回览了一下只读路由配置的脚本, 下面是微软官方提供的示例

ALTER AVAILABILITY GROUP [AG1]
 MODIFY REPLICA ON
N‘COMPUTER01‘ WITH
(SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
ALTER AVAILABILITY GROUP [AG1]
 MODIFY REPLICA ON
N‘COMPUTER01‘ WITH
(SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N‘TCP://COMPUTER01.contoso.com:1433‘));

在进行指定只读路由的时候,发现他使用的是实例名字COMPUTER01.contoso.com,所以猜想可能和这个有关系,要使用IP地址估计问题就能解决

修改前一篇的只读路由:http://www.cnblogs.com/dcz2015/p/5444438.html 如下:

①删除只读路由表:

ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N‘WIN-14VNU7CGQO1‘ WITH
(
    PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=NONE)
);
GO
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N‘WIN-14VNU7CGQO2‘ WITH
(
    PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=NONE)
);
GO

②添加只读路由:

--①配置A副本的只读路由属性(ReadOnly代表‘只读意向’)
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N‘WIN-14VNU7CGQO1‘ WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
--②配置A副本的只读路由URL
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N‘WIN-14VNU7CGQO1‘ WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N‘tcp://193.160.26.32:1433‘));
--③配置B副本的只读路由属性
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N‘WIN-14VNU7CGQO2‘ WITH (SECONDARY_ROLE (ALLOW_CONNECTIONS = READ_ONLY));
--④配置B副本的只读路由URL
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N‘WIN-14VNU7CGQO2‘ WITH (SECONDARY_ROLE (READ_ONLY_ROUTING_URL = N‘tcp://193.160.26.28:1433‘));
--⑤配置A副本作为主副本时候的只读路由表
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N‘WIN-14VNU7CGQO1‘ WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=(‘WIN-14VNU7CGQO2‘,‘WIN-14VNU7CGQO1‘)));
--⑥配置B副本作为主副本时候的只读路由表
ALTER AVAILABILITY GROUP [testAG]
MODIFY REPLICA ON N‘WIN-14VNU7CGQO2‘ WITH (PRIMARY_ROLE (READ_ONLY_ROUTING_LIST=(‘WIN-14VNU7CGQO1‘,‘WIN-14VNU7CGQO2‘)));
GO    

在客户端进行测试:

读过程:

写过程:

时间: 2024-09-30 05:21:03

我踩过的Alwayson的坑!的相关文章

微信小程序项目踩过的几个坑

一.前言 近期,开始了一段辛酸的还未开始就已经结束的"创业"(参见我的第二次创业,以梦为马,莫负韶华).大体上是开发了一款微信小程序,关于创业这件事情就不细说了,本文主要介绍一下开发小程序的过程中踩过的几个坑. 二.注册 开发一款功能全乎的小程序,在未动键盘开始码代码之前就要涉及到账号注册.微信认证.支付申请等等,这里面也有一些坑. 首先是必须要企业认证才能有微信支付功能,以个人名义申请不能进行支付.微信认证还算容易,只需要支付300元即可.支付申请的时候会让你选择需要申请的经营种类,

iOS开发之记一次App卡顿Bug的解决历程(踩了一个StoryBoard的坑)

虽然今天是周末,但是还是要学习的不是.写这篇博客的目的呢是记录一下自己在上次项目迭代中踩的坑,不过这个坑已经填上了.虽然坑不大,但是踩上去肯定能崴脚.其实还是那句话,在没人给你指路的情况下,踩的坑多了,慢慢的就成长了.为了填今天要讲的这个坑,午觉都没睡呢.当然今天博客的内容并不高深,而且出现的几率还是蛮大的,所以喽就记录一下.也许你已经踩过,或者你已经将此坑填上,但是今天是我踩了一脚呢,没办法,还是记录一下吧. 解决历程用一个字描述就是:“删”. 一.描述这个“坑” 首先呢,我们先来看一下这个B

HTML5移动应用开发最容易踩到的几个坑

01/移动应用中HTML5的新特性 工欲善其事,必先利其器.我比较推崇的学习技术的方式,是先整体了解,然后结合实际需求,再做针对性的学习.整体了解的方式,比较建议是直接看官网的API文档,这里可以推荐几个网站: http://www.w3school.com.cn/html5/index.asp, https://developer.mozilla.org/zh-CN/docs/Web/Guide/HTML/HTML5, http://www.html5rocks.com, http://can

Visual Studio 2015下编译zmq项目下其他项目踩进的项目引用坑

PS.在之前的一篇文章中介绍了如何用Visual Studio 2015编译zmq,在编译同解决方案中除了libzmq之外的项目例如inproc_thr时会报错误,具如下: Severity Code Description Project File Line Suppression State Error LNK1181 cannot open input file 'libzmq.lib' inproc_thr E:\zeromq4-1-master\zeromq4-1-master\bui

谈谈我用Unity5的AssetBundle踩到的几个坑

在上段时间摸索了Unity5的assetbundle用法之后,我在项目里面全面的使用起来,于是发现了一些坑,这里和大家分享一下,顺便说说我是怎样解决的. 首先是图集打包的问题.这个问题在unity5.2版本已经解决了,但在5.2之前确实是一个bug来的.具体的表现是,你把同一个图集标签的散图打包成同一个assetbundle时,这个assetbundle既包含了图集的大图,也包含了散图本身,变成了重复打包,容量暴增.这个问题困扰了我一小段时间,后来尝试着下载了个unity5.2,就没有这个问题了

那些年踩过的WebAPI的坑(一)

---恢复内容开始--- Visual Studio创建一个web项目, 在下一步的时候创建WebAPI项目的时候勾选web API之后,系统会生成一个web项目. 首先看一下webapi的路由配置,在App_start/webapiconfig.cs中,可以看到如下代码: 1 public static void Register(HttpConfiguration config) 2 { 3 // Web API configuration and services 4 5 // Web A

踩了的Dockerfile的坑

1.Dockerfile VOLUME的目录,RUN命令操作该目录无效 VOLUME $APP_HOME RUN mkdir -p $APP_HOME && mkdir -p $APP_HOME/config && mkdir -p $APP_HOME/logs RUN chown -R $USER_GROUP_NAME "$APP_HOME" Dockerfile VOLUME了目录$APP_HOME之后,RUN 命令的 mkdir -p $APP_H

关于服务器端的Json文件的接收,踩了一早上的坑的问题

JSON文件的发送和接收 服务器端接收的JSON文件也是String型的文件,因此不可以直接写成如下的格式,此错误格式下无法找到发送的{}内的数据,服务器会报错提示无法找到你需要的类型数据,也就是根本不存在一个JSONObject被接收到. 因此必须执行如下的格式,通过String型接收,该结果通过fastjson进行map的提取和使用,新学的fastjson~~ 原文地址:https://www.cnblogs.com/kobe961231/p/10506738.html

过去一年踩下的坑,价值好几百万

第一个关键词:复盘 在商业战略上复盘有两个好处.第一个是找到亮点,对于可行的一些试点项目投入更多资源扩大规模.第二个是我们犯过什么错,犯过的错误能不能写下来不再犯.今天就来盘点一下去年我们范下的那些严重错误: 1. 低估问题的难度 如果去看上一篇文章大概还可以看到我对于能从一堆乱麻中找到所有问题,排好优先级一个一个来理顺解决这件事情是抱着痴迷的态度的. 但是由于认知的问题,包括对于个人本身能力的认知以及对于问题的认知都决定了"外来人员" 是很难在短期内从根本上解决问题的.举个栗子: 由