什么是token及怎样生成token - 路飞撸代码 - 博客园

mikel阅读(1161)

来源: 什么是token及怎样生成token – 路飞撸代码 – 博客园

什么是token

  Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。
  基于 Token 的身份验证
  1. 使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。流程是这样的:
  2. 客户端使用用户名跟密码请求登录
  3. 服务端收到请求,去验证用户名与密码
  4. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  5. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  6. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  7. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
  8. APP登录的时候发送加密的用户名和密码到服务器,服务器验证用户名和密码,如果成功,以某种方式比如随机生成32位的字符串作为token,存储到服务器中,并返回token到APP,以后APP请求时,
  9. 凡是需要验证的地方都要带上该token,然后服务器端验证token,成功返回所需要的结果,失败返回错误信息,让他重新登录。其中服务器上token设置一个有效期,每次APP请求的时候都验证token和有效期。

token的优势

  1.无状态、可扩展

在客户端存储的Tokens是无状态的,并且能够被扩展。基于这种无状态和不存储Session信息,负载负载均衡器能够将用户信息从一个服务传到其他服务器上。如果我们将已验证的用户的信息保存在Session中,则每次请求都需要用户向已验证的服务器发送验证信息(称为Session亲和性)。用户量大时,可能会造成  一些拥堵。但是不要着急。使用tokens之后这些问题都迎刃而解,因为tokens自己hold住了用户的验证信息。

2.安全性

请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)。即使在客户端使用cookie存储token,cookie也仅仅是一个存储机制而不是用于认证。不将信息存储在Session中,让我们少了对session操作。token是有时效的,一段时间之后用户需要重新验证。我们也不一定需要等到token自动失效,token有撤回的操作,通过token revocataion可以使一个特定的token或是一组有相同认证的token无效。

3.可扩展性

Tokens能够创建与其它程序共享权限的程序。例如,能将一个随便的社交帐号和自己的大号(Fackbook或是Twitter)联系起来。当通过服务登录Twitter(我们将这个过程Buffer)时,我们可以将这些Buffer附到Twitter的数据流上(we are allowing Buffer to post to our Twitter stream)。使用tokens时,可以提供可选的权限给第三方应用程序。当用户想让另一个应用程序访问它们的数据,我们可以通过建立自己的API,得出特殊权限的tokens。

4.多平台跨域

我们提前先来谈论一下CORS(跨域资源共享),对应用程序和服务进行扩展的时候,需要介入各种各种的设备和应用程序。Having our API just serve data, we can also make the design choice to serve assets from a CDN. This eliminates the issues that CORS brings up after we set a quick header configuration for our application.只要用户有一个通过了验证的token,数据和资源就能够在任何域上被请求到。Access-Control-Allow-Origin: *

  5.基于标准

  创建token的时候,你可以设定一些选项。我们在后续的文章中会进行更加详尽的描述,但是标准的用法会在JSON Web Tokens体现。最近的程序和文档是供给JSON Web Tokens的。它支持众多的语言。这意味在未来的使用中你可以真正的转换你的认证机制。

token原理

1.将荷载payload,以及Header信息进行Base64加密,形成密文payload密文,header密文。

2.将形成的密文用句号链接起来,用服务端秘钥进行HS256加密,生成签名.

3.将前面的两个密文后面用句号链接签名形成最终的token返回给服务端

注:

(1)用户请求时携带此token(分为三部分,header密文,payload密文,签名)到服务端,服务端解析第一部分(header密文),用Base64解密,可以知道用了什么算法进行签名,此处解析发现是HS256。

(2)服务端使用原来的秘钥与密文(header密文+”.”+payload密文)同样进行HS256运算,然后用生成的签名与token携带的签名进行对比,若一致说明token合法,不一致说明原文被修改。

(3)判断是否过期,客户端通过用Base64解密第二部分(payload密文),可以知道荷载中授权时间,以及有效期。通过这个与当前时间对比发现token是否过期。

token实现思路

1.用户登录校验,校验成功后就返回Token给客户端。

2.客户端收到数据后保存在客户端

3.客户端每次访问API是携带Token到服务器端。

4.服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码

token代码生成工具类demo

package com.frank.common.utils;

import com.alibaba.fastjson.JSON;
import com.frank.common.entity.TokenHeader;
import com.frank.common.entity.TokenPlayload;
import com.frank.common.entity.User;

import java.rmi.server.UID;
import java.util.UUID;

/**
* Description:Token生成工具
* 第一部分我们称它为头部(header),第二部分我们称其为载荷(payload, 类似于飞机上承载的物品),第三部分是签证(signature).
* Auth: Frank
* Date: 2017-11-02
* Time: 下午 5:05
*/
public class TokenUtil {

public static final String TOKEN_AES_KEY = “xiangli8Token”;
public static final String REFREH_TOKEN_AES_KEY = “xiangli8RefreshToken”;
public static final String JWT_TYP = “JWT”;
public static final String JWT_ALG = “AES”;
public static final String JWT_EXP = “30”;
public static final String JWT_ISS = “xiangli8”;

/**
* 获得token
* @param data 自定义数据
* @param <T> 自定义数据
* @return
* @throws Exception
*/
public static <T> String getToken(T data) throws Exception {
TokenPlayload<T> userTokenPlayload = new TokenPlayload<>();
userTokenPlayload.setExpData(data);
String jwt = createJWT(userTokenPlayload);
return jwt;
}

/**
* 生成jwt的header部分内容
* @return
* @throws Exception
*/
private static String tokenHeaderBase64() throws Exception {
TokenHeader tokenHeader = new TokenHeader();
tokenHeader.setTyp(JWT_TYP);
tokenHeader.setAlg(JWT_ALG);

String headerJson = JSON.toJSONString(tokenHeader);

String headerBase64 = Base64Util.encryptBASE64(headerJson.getBytes());

return headerBase64;
}

/**
* 生成jwt的payload部分内容
* @param tokenPlayload
* @param <T>自定义的数据块
* @return
* @throws Exception
*/
private static <T> String tokenPayloadBase64(TokenPlayload<T> tokenPlayload) throws Exception {
tokenPlayload.setIss(JWT_ISS);
tokenPlayload.setExp(JWT_EXP);

tokenPlayload.setIat(String.valueOf(System.currentTimeMillis()));

String headerJson =JSON.toJSONString(tokenPlayload);

String headerBase64 = Base64Util.encryptBASE64(headerJson.getBytes());

return headerBase64;
}

/**
* 生成JWT
* @return
*/
public static <T> String createJWT(TokenPlayload<T> tokenPlayload) throws Exception {
StringBuilder jwtSb = new StringBuilder();
StringBuilder headerPlayloadSb = new StringBuilder();

String tokenHeaderBase64 = tokenHeaderBase64();
String tokenPayloadBase64 = tokenPayloadBase64(tokenPlayload);

jwtSb.append(tokenHeaderBase64);
jwtSb.append(“.”);
jwtSb.append(tokenPayloadBase64);
jwtSb.append(“.”);

headerPlayloadSb.append(tokenHeaderBase64);
headerPlayloadSb.append(tokenPayloadBase64);

String headerPlayloadSalt = SaltUtil.addSalt(headerPlayloadSb.toString());

String key = AesUtil.initKey(TOKEN_AES_KEY+tokenPlayload.getIat());

String signature = Base64Util.encryptBASE64(AesUtil.encrypt(headerPlayloadSalt.getBytes(),key));

jwtSb.append(signature);

return Base64Util.encryptBASE64(jwtSb.toString().getBytes());
}

/**
* 校验token是否是服务器生成的,以防token被修改
* @param jwtBase64
* @return
* @throws Exception
*/
public static <T> boolean verifyJWT(String jwtBase64) throws Exception {
String jwt = new String (Base64Util.decryptBASE64(jwtBase64));

if(!jwt.contains(“.”)){
return false;
}

String[] jwts = jwt.split(“\\.”);
if(jwts.length<3){
return false;
}

TokenPlayload tTokenPlayload = JSON.parSEObject(new String(Base64Util.decryptBASE64(jwts[1])),TokenPlayload.class);
String key = AesUtil.initKey(TOKEN_AES_KEY+tTokenPlayload.getIat());

//解析出header跟playload
StringBuilder headerPlayloadSb = new StringBuilder();
headerPlayloadSb.append(jwts[0]);
headerPlayloadSb.append(jwts[1]);

//解析signature
String headerPlayloadSalt = new String (AesUtil.decrypt(Base64Util.decryptBASE64(jwts[2]),key));

return SaltUtil.verifyPwd(headerPlayloadSb.toString(),headerPlayloadSalt);
}

 

public static void main(String[] args) throws Exception {
String jwt = getToken(new User(1L,”你是逗逼”));
System.out.println(“jwt:”+jwt);
System.out.println(“verifyJWT:”+verifyJWT(jwt));
}
}

使用说明

1,根据上面生成一个由base64编码的token,该token由Header,Payload,Signature组成。

2,token作为用户请求的标识,客户端保存这token的全部信息。服务端只需要保存token的Signature部分。

3,服务端把token的Signature存于redis和服务器的数据库中。

4,客户端请求的数据附带token,服务端拿到token,首先校验token,以防token伪造。校验规则如下:

4.1,拆分出token的Header,Payload,Signature。

4.2,校验Signature,通过token的header和payload生成Signature,看看生成的Signature是否和客户端附带上来的Signature一致。如果一致继续请求操作,不一致则打回操作

4.3,查看Signature是否存在服务器的redis和数据库中。如果不存在则打回请求操作

win10上 安装Sqlserver2008R2数据库提示.NET Framework3.5不存在,解决之后仍然提示兼容问题安装不成功_一米阳光-CSDN博客

mikel阅读(4195)

来源: win10上 安装Sqlserver2008R2数据库提示.NET Framework3.5不存在,解决之后仍然提示兼容问题安装不成功_一米阳光-CSDN博客

最近项目开发过程中,需要在win10系统上安装SQLServer2008R2的时候,刚开始提示需要安装.NET Framework3.5版本,通过360软件管家安装之后,仍然不行,安装SQLServer的时候提示截图如下:

试了网上好多方法,仍然不行,然后参考了其他网站的一个解决方法,采用cab格式的.NET Framework 3.5离线安装包格式进行安装。

安装方法:

先把下载的名为NetFx3.cab的离线安装包放到Win10系统盘C:\Windows文件夹里。

然后以管理员身份运行命令提示符(按 win + x ,如下图 ),输入并回车运行以下命令:

 

dism /online /Enable-Feature /FeatureName:NetFx3 /Source:”%windir%” /LimitAccess

等待部署进度100%即可。
cab格式的.NET Framework3.5下载地址:http://download.csdn.net/detail/zhangzuomian/9789495

参考网站地址:https://www.windows10.pro/net-framework-3-5-netfx3-cab-download/

这样就把.NET Framework3.5安装成功了。

安装.NET Framework3.5之后,继续安装SQLserver,刚开始以兼容模式和管理员模式进行SQLserver2008R2数据库文件的安装,但是最后总是提示失败。网上看了很多解决方法,有的朋友说要更换系统,有的说需要下载sp3,最后仍然没有解决。

怎么解决呢?最后发现win10下安装sqlserver2008R2的时候,不要使用兼容模式安装,然后也不用右键选择管理员模式安装,直接双击安装就可以。

我也不知道为什么会这样,反复试了几次,用兼容模式安装会提示失败,不用兼容模式就没有问题。
————————————————
版权声明:本文为CSDN博主「张懿勉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ZhangZuoMian/article/details/64905543

安装Sql server 2008时提示没有安装.net 3.5的解决办法_doyouknowm的专栏-CSDN博客

mikel阅读(1605)

来源: 安装Sql server 2008时提示没有安装.net 3.5的解决办法_doyouknowm的专栏-CSDN博客

将dotNetFx35setup.exe拷贝至对应目录下(由操作系统而定),如下:

x86\redist\DotNetFrameworks\dotNetFx35setup.exe

x64\redist\DotNetFrameworks\dotNetFx35setup.exe

如果还有其他问题,比如WindowsInstaller 4.5的安装失败或者语言包的问题,同样的处理方式。
————————————————
版权声明:本文为CSDN博主「doyouknowm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/doyouknowm/article/details/61617892

Notepad++ 搜索功能学习总结_bcbobo21cn的专栏-CSDN博客

mikel阅读(1511)

来源: Notepad++ 搜索功能学习总结_bcbobo21cn的专栏-CSDN博客

一 实例

先看一下查找菜单;

查找对话框;

 

标记功能;选中 标记所在行;

 

标记后的情况如下图;

 

 

文件查找功能;下图是在 C:\Windows\Microsoft.NET\Framework\v4.0.30319目录下的所有文件(含子目录)中查找字符串”xml”;

 

最后找到的结果如下所示;

 

增量查找;我操作的时候 增量查找 功能应该是默认开启的; 在下部输入框输入查找内容,每输入一个字符就会自动显示文档中匹配的部分,不用全部输入完再打回车才显示,这就是增量查找的含义;

 

列编辑;按住Alt后,即是列编辑模式;按住Alt,再用鼠标选取,可以不用整行的选取;如下图;

 

二 Notepad++查找功能
Notepad++中的高级查找

无论对于哪一种编辑器,基本上都支持正则表达式查找,在Notepad++中也不例外,今天我们一块看下如何使用正则表达式进行查找。

工具/原料
Notepad++
方法/步骤
1
准备以下字符串用来演示
abcdeab
cdeabcde
abcd
eabcde

2
基于扩展的查找
基于扩展的查找不能算是真正的正则表达式搜索,因此这种查找方式仅是提供了支持转义字符。主要常用的转义字符包含了:\r\n\t等。
我们分别使用下面的搜索条件进行查找:
a.*\r\n
abcd\r\n
会发现使用a.*\r\n是无法查找到内容。这也说明了在我们选择“扩展”项时不支持正则条件。

3
使用正则表达式
对于 正则表达式的使用方法我们就不介绍了,这里我们搜索abcd字符串。使用下面的正则进行匹配,为了便于显示,我们使用“标记”功能:
a.+?d
上面的正则表达式的意思是搜索字符串中以a开始,后面有一个或多个字符(.代表除了\n之外的其他字符,+代表匹配一次或多次,?代表非贪婪,即从当前字符开始向后一个一个字符的匹配),最后以d字符结尾。
我们会发现匹配到了4个,可能就会有人问了,那第一行结尾的ab与第二行的cd也应该匹配啊,其实原因就是在于对于正则表达式来说,回车换行代表了一个新的段落开始,如果想匹配那么就涉及到了匹配模式,下面会说明如何进行匹配。

4
匹配新行
为了解决第3步中我们的问题,在Notepad++中提供了“匹配新行”功能,如果我们选中了,那么就会匹配成功第3步所讲的字符串。

关于NotePad++中的查找模式以及符号
Word、Excel、txt等文字编辑文件中有一些平时不可见的符号,如制表符、换行符、软回车等。当我们需要替换或者批量删除这些特殊的符号的时候,NotePad++就是一个很强大的工具了。

\t:制表符。在NotePad++中显示为向右的箭头
\n:换行符。在NotePad++中显示为LF
\r:软回车。在NotePad++中显示为CR
\0:??
\x:??
————————————————
版权声明:本文为CSDN博主「bcbobo21cn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/bcbobo21cn/article/details/51803773

sql server 2008 r2 双机热备操作流程_lance_kl的博客-CSDN博客

mikel阅读(601)

来源: sql server 2008 r2 双机热备操作流程_lance_kl的博客-CSDN博客

一、配置步骤:

1.两台服务器,主服务器,从服务器,两台服务器都安装SQL Server 2008R2并且安装相同表结构的数据库(需要实时同步的数据库)

2.主服务器数据库安装完毕,打开SQL Server 配置管理器,把SQL Server 代理服务打开(已打开请忽略)

3.登录主服务器数据库,从数据库左侧菜单栏找到->复制->本地发布,右击新建发布

4.默认主服务器当作分发服务器

5.快照文件夹最好新建一个目录(需要手动在D盘新建目录),默认目录会有权限问题(对于新手权限问题不好解决)

6.选择需要发布的数据库

7.发布类型选择事务发布(发布类型的区别可自行百度,此处不做叙述)

8.选择需要发布的表(需要同步到从服务器数据库表的数据)

9.筛选表行(意思是表中的哪些字段你不需要同步到从服务器)

10.快照代理,选择->立即创建快照并使快照保持可用状态,以初始化订阅

11.代理安全性,点击安全设置,按照红色框中设置即可

12.向导操作,选择->创建发布->下一步

13.完成该向导,填写一个发布名称,点击完成,到此步骤主服务器本地订阅发布已经完成

14.登录从服务器数据库,从数据库左侧菜单栏找到->复制->本地订阅->右击新建订阅->选择查找SQL Server 发布服务器,数据库服务器名称要是主服务器计算机名称,输入登录名和密码

15.选择刚才主服务器发布的订阅

16.选择运行分发代理的位置,勾选第一个,如果选择第二个也需要开启从服务器SQL Server代理服务

17.选择订阅服务器(从服务器),订阅数据库需要同步的数据库(主服务器和从服务器热备份的数据库结构需要一致)

18.分发代理安全性,推荐按红色框中设置,如下图:(注意这里的账号密码,为相应服务器的实际账户密码)

19.同步计划选择连续运行

20.初始化订阅

21.向导操作->创建订阅->下一步->完成

22.刷新从服务器左侧菜单栏下的本地订阅,会出现刚刚创建好的订阅,为了验证设置是否成功,右击创建好的订阅->查看同步状态,如图显示同步正在进行则说明双机热备份设置成功

23.测试配置是否生效,在主服务器数据库通过updata语句修改某个表的字段值,然后查看从服务器数据库是否对应修改即可

 

 

二、SQL Server发布订阅异常处理

1.强制删除发布命令:EXEC SP_REMOVEDBREPLICATION ‘发布数据库名称’;

2.SQL2008发布订阅报错“进程无法在WIN-SERVER 上执行 sp_replcmds”

执行以下SQL脚本

①.首先执行: ALTER AUTHORIZATION ON DATABASE::[数据库名] TO [SQL登录用户名]

②.然后执行:

USE 数据库名

GO

sp_changedbowner ‘SQL登录用户名’

③.最后执行:

EXEC sp_repldone @xactid =NULL, @xact_segno =NULL, @numtrans = 0, @time =0, @reset =1

EXEC sp_replflush

④.如果还是不可以, 重启SQL Server Agent服务。

Log4Net 日志查看工具_随心-CSDN博客

mikel阅读(933)

来源: Log4Net 日志查看工具_随心-CSDN博客

对于网站开发来说,如果我们采用了log4net来记录日志,那么查看日志最常用的方式就是直接去文件夹下面看,但这样做及其的不方便,于是乎借用log4net的 UdpAppender 开发了下面这样的一个工具用于实时查看日志。

该工具目前支持的功能如下:

支持同时收集多个APP的日志,并且提供筛选功能
支持按照线程ID进行筛选日志
支持通过日志名称筛选日志
支持一键清空显示区域的所有日志
支持自动滚动或者禁止自动滚动
支持置顶或者取消置顶
支持复制配置,复制配置之后粘贴到APP的配置文件中即可使用
支持自定义监听端口
支持调整窗口的透明度
支持调整显示区域的字体大小
界面如下:

 

相关代码已经开源,地址为:https://github.com/cxwl3sxl/LogViewer

程序下载:https://download.csdn.net/download/cxwl3sxl/10330711
————————————————
版权声明:本文为CSDN博主「cxwl3sxl」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cxwl3sxl/article/details/79835851

 SQL Server 2008 R2双机热备_wangqi791975的博客-CSDN博客

mikel阅读(720)

来源: (1条消息) SQL Server 2008 R2双机热备_wangqi791975的博客-CSDN博客

作用:
1、可以实施响应备份事务,备份时间间隔较短
2、当主数据库挂掉时可以切到备份数据库服务器,程序不会挂掉。
3、可以用于读写分离,增删改操作在主数据库服务器上进行,查询在备份数据库服务器上进行。一方面提高软件执行效率,另一方面也减轻主库压力。

操作:
1、需要2台分别安装SQL Server 2008R2的数据库服务器。
2、这里有3个名称需要搞清楚
发布服务器:主库所在的服务器。
分发服务器:用于传递当主库发生变化(增删改)时发送到订阅服务器的
订阅服务器:备份服务器
3、新建发布服务器:

 

 

 

4、新建订阅服务器

 

 

 

 

 

 

————————————————
版权声明:本文为CSDN博主「IngGoer」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wangqi791975/article/details/50208071

excel怎么删除指定行?Excel删除指定颜色的行的教程

mikel阅读(1482)

我们在使用Excel的时候,有时候需要删除一些单元格或者行,那么Excel中如何删除指定颜色的行呢?

1、我们在图示空白的单元格输入测试数据和一些带有颜色的行。

2、我们按下CTRL+F打开“找”窗口,或者在菜单栏依次点击“开始-查找/替换”。

3、接着我们在弹出的查找框内点击“选项-设置查找的格式”。

4、依次点击“格式-从单元格选择格式”,用吸管直接吸取黄色单元格。

5、接着我们点“全部查找”后,按ctrl+A即可全选所有黄色单元格。

6、最后右击弹出菜单栏,点击删除,选择整行即可。如图所示,已经删除了所有的黄色单元格。

高并发下的服务器架构演变 - rookie丶 - 博客园

mikel阅读(756)

来源: 高并发下的服务器架构演变 – rookie丶 – 博客园

在如间的网络环境下,高并发的场景无处不在,特别在面试如何解决高并发是一个躲不过的问题,即使生产环境达不到那么高的qps但是也应该给自己留条后路来应对日后可能发生的高并发场景,不用匆忙的加班加点的进行重构。

在应对日常高并发场景常常会有这么几个方法:

  1. 集群&负载均衡SLB
  2. 读写分离&分库分表
  3. 缓存
  4. 异步队列(RebbitMQ)
  5. 分布式系统、微服务

接下来就由浅入深分别来介绍下这几个方法是怎么应用到服务器并且解决高并发的,首先我们先来看下最原始的也是最简单的服务器与应用程序关系。

                                                                      图1

如图1所示在一台服务器上承载了数据库、文件系统、应用程序的所有功能,这就导致即使低qps的情况下服务器的内存或者cpu占比都非常高,用过SQLServer的同僚们都知道为了达到最高效快速的数据查询、存储及运算支持SQL server默认会尽可能的占用内存及CPU来达到自己的目的,从而导致我们的应用程序在处理一些运算或者请求量相对升高时应用程序就会变得非常慢,这时候我们就该考虑升级我们现有的服务器了,当然最高效也是最便捷的方式是升级硬件(cpu、内存、硬盘),这也是最容易达到瓶颈的毕竟一台服务的硬件也是有瓶颈的而且费用也是相当相当高昂的,一般情况下我们会选择我们最开始提到解决高并发方法中分布式来升级我们图1的单一服务器系统架构。

                                                                         图2

如图2所示我们由一台服务器转为三台服务器互相协作的方式来处理每次请求,这也是简单的分布式系统每台服务器各司其职再也不会发生单一应用占用大量cpu或内存的情况导致请求变得缓慢,但是就图2而言的服务器架构的承载能力也是非常有限的,当请求量上升后可能就扛不住宕机了。

一般这时候我们就要分析发生宕机的原因,从图2便知只有服务器A或者服务器B最有可能出现问题,根据以往的经验在请求量升高时数据库会承载绝大部分的压力,如果数据库崩了那么整个应用就会处于不可用的状态,那么为了缓解数据库的压力,我们很自然的就会想到利用缓存,这也是高并发场景下最常用也是最有效最简单的方案,利用好缓存能让你的系统的承载能力提示几倍甚至十几倍几十倍。熟悉二八原则的同僚们都知道80%请求的数据都集中在20%的数据上,虽然有些夸张但是意思就是这么个意思。缓存又分为本地缓存和分布式缓存,本着分布式的原则,我们一般都会选用分布式缓存同时也是为后期做分布式集群打下基础。

                                                                      图3

如图3所示在图2的基础上增加了一台缓存服务器D来储存我们的缓存数据,一般我们会采用redis来存放缓存数据,至于memcache现在应用的频率是非常低的。现在当请求到达应用程序时会优先访问缓存服务器D,若存在缓存数据就直接返回给客户端如果不存在缓存数据才会去数据库获取数据返回给客户端同时将数据保存到缓存服务器D设置缓存失效时间这样下次请求时就不用到数据库查询数据了从而达到减轻数据库压力的目的。虽然缓存能抵挡大部分的请求,但是我们也要做好防止缓存击穿、穿透和雪崩的问题来提升系统的稳定性。

随着业务量的增多和繁多的业务种类图3的系统架构也会慢慢达到瓶颈支撑不住多样化的业务需求,这时候我们就应该采用集群的方式来达到负载均衡的目的,将请求平均的分散到多台服务器来拓展应用程序的承载能力。

                                                                        图4

如图示4所示由服务器A-1、服务器A-2共同承载用户的请求来提高系统的承载能力也就是我们最开始说到集群,出现集群的地方必然少不了负载均衡,图4我们由nginx来实现请求的分发来达到负载均衡的目的。在设计图3的架构的时候我们有说到本地缓存,如果是采用本地缓存而不是分布式缓存那么系统架构就存在一个比较大的缺陷,因为一个请求过来是由nginx区分发的如果我们再用本地缓存那么在在服务器A-1和服务器A-2上可能存在大量相同的本地缓存这样就得不偿失了容易造成服务器资源的浪费严重的还会拖累服务器的性能,利用分布式缓存的好处在于我们不管有多少个应用服务器所有的缓存都是共享的。

图4的服务器架构应该是目前中小型应用中最常用的,而且系统的整体承载能力也相当不错,不过随着业务的发展流量与日俱增,图3的服务器架构也很难保证系统的稳定,特别是日常流量峰值的一些时段图3的系统可能时常会面临奔溃的危险,这时候就要重新分析各服务器的压力承载情况了,显而易见最可能出现问题的就是数据库服务器,终于要对数据库下手了,当下最有效的方法就是就写分离,还是遵循二八原则80%的数据操作都是查询操作。

 

                                                                        图5

如图5所示在图4的基础上由单一的数据库变为主从数据库从库负责数据的查询操作主库负责数据增删改操作,但请求操作主库后主库将操作日志执行到从库达到主从数据一致的目的,但是主从分离后不可能避免的一个问题就是主从数据一致性会有延迟,数据同步延迟的问题只能尽可能的减小数据延迟的时间,但对一些时效性非常高或者不能容忍数据延迟的请求只能做一些妥协,这类操作的crud都在主库上操作这样就避免数据延迟的问题,对一些对于数据时效性不那么严格的请求可以将这部分的查询操作由从库去承载,对于主从数据库个人以为和应用集群是一样的可以理解为集群数据库只不过在请求的分发上制定了规则(主库处理更新、从库处理查询)。

队列下回补充。。。个人对队列的理解不够透彻需要好好组织下再发表。。。

JQuery字符串替换replace方法_王安的博客-CSDN博客_jq字符串替换

mikel阅读(1095)

来源: JQuery字符串替换replace方法_王安的博客-CSDN博客_jq字符串替换

在日常的js开发中,常常会用到JQuery

当要把字符串中的内容替换时,如果使用类似C#的string.replace方法,如下

var str=’aabbccaa’;

str=str.replace(‘aa’,’dd’);

结果是  str=’ddbbccaa’

后面的aa没有被替换,原因是这个写法替换的只有第一次出现的aa,后面的就无效了。

但是,可以使用正则表达式进行替换,模式需要指定为g,表示检索全局。

代码如下:

var str=’aabbccaa’;

var reg=/aa/g;

str=str.replace(reg,’dd’);

结果是  str=’ddbbccdd’

JQuery结合正则表达式,替换的功能会变得更强大。

批量替换多个字符的代码:

var reg=/Q355B|坏|弯|合金|Q55B|Q345B|锈|修不好|短|代|先入|(检尺)/g;
res=spec.replace(reg,”);