4月3
nginx的upstream目前支持的5种方式的分配

1、轮询(默认)
每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 
upstream backserver { 
server 192.168.0.14; 
server 192.168.0.15; 


2、指定权重
指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 
upstream backserver { 
server 192.168.0.14 weight=8; 
server 192.168.0.15 weight=10; 


3、IP绑定 ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 
upstream backserver { 
ip_hash; 
server 192.168.0.14:88; 
server 192.168.0.15:80; 


4、fair(第三方)
按后端服务器的响应时间来分配请求,响应时间短的优先分配。 
upstream backserver { 
server server1; 
server server2; 
fair; 


5、url_hash(第三方)
按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 
upstream backserver { 
server squid1:3128; 
server squid2:3128; 
hash $request_uri; 
hash_method crc32; 


4月3
1、水平切分:
通俗的来讲
例:QQ的用户表。假设QQ的用户有100亿,如果只有一张表,每个用户登录的时候数据库都要从这100亿中查找,会很慢很慢。如果将这一张表分成100份,每张表有1亿条,就小了很多,比如qq_user_0,qq_user_1,qq_user_2...qq_user_99表。

用户登录的时候,可以将用户的id%100,那么会得到0-99的数,查询表的时候,将表名qq跟取模的数连接起来,就构建了表名。比如123456789用户,取模的89,那么就到qq_user_89表查询,查询的时间将会大大缩短。

这就是水平切分。

2、垂直切分:

垂直切分指的是:表的记录并不多,但是字段却很长,表占用空间很大,检索表的时候需要执行大量的IO,严重降低了性能。这时需要把大的字段拆分到另一个表,并且该表与原表是一对一的关系。

例如学生答题表tt:有如下字段:

Id name 分数 题目 回答

其中题目和回答是比较大的字段,id name 分数比较小。

如果我们只想查询id为8的学生的分数:select 分数 from tt where id = 8;虽然知识查询分数,但是题目和回答这两个大字段也是要被扫描的,很消耗性能。但是我们只关心分数,并不想查询题目和回答。这就可以使用垂直分割。我们可以把题目单独放到一张表中,通过id与tt表建立一对一的关系,同样将回答单独放到一张表中。这样我们插叙tt中的分数的时候就不会扫描题目和回答了。

3、其他要点:

1)存放图片、文件等大文件用文件系统存储。数据库只存储路径,图片和文件存放在文件系统,甚至单独存放在一台服务器(图床)。

2)数据参数配置。

最重要的参数就是内存,我们主要用的innodb引擎,所以下面两个参数调的很大:

innodb_additional_mem_pool_size=64M

innodb_buffer_pool_size=1G

对于MyISAM,需要调整key_buffer_size,当然调整参数还是要看状态,用show status语句可以看到当前状态,以决定该调整哪些参数。
3月25

分布式事务解决方案

20:34编程杂谈  From: 本站原创
分布式事务了解吗?你们是如何解决分布式事务问题的?
一般来说,分布式事务的实现主要有以下 5 种方案:

XA 方案
TCC 方案
本地消息表
可靠消息最终一致性方案
最大努力通知方案

两阶段提交方案/XA方案
所谓的 XA 方案,即:两阶段提交,有一个事务管理器的概念,负责协调多个数据库(资源管理器)的事务,事务管理器先问问各个数据库你准备好了吗?如果每个数据库都回复 ok,那么就正式提交事务,在各个数据库上执行操作;如果任何其中一个数据库回答不 ok,那么就回滚事务。

这种分布式事务方案,比较适合单块应用里,跨多个库的分布式事务,而且因为严重依赖于数据库层面来搞定复杂的事务,效率很低,绝对不适合高并发的场景。如果要玩儿,那么基于 Spring + JTA 就可以搞定,自己随便搜个 demo 看看就知道了。

这个方案,我们很少用,一般来说某个系统内部如果出现跨多个库的这么一个操作,是不合规的。我可以给大家介绍一下, 现在微服务,一个大的系统分成几十个甚至几百个服务。一般来说,我们的规定和规范,是要求每个服务只能操作自己对应的一个数据库。

如果你要操作别的服务对应的库,不允许直连别的服务的库,违反微服务架构的规范,你随便交叉胡乱访问,几百个服务的话,全体乱套,这样的一套服务是没法管理的,没法治理的,可能会出现数据被别人改错,自己的库被别人写挂等情况。

如果你要操作别人的服务的库,你必须是通过调用别的服务的接口来实现,绝对不允许交叉访问别人的数据库。


TCC 方案
TCC 的全称是:Try、Confirm、Cancel。

Try 阶段:这个阶段说的是对各个服务的资源做检测以及对资源进行锁定或者预留。
Confirm 阶段:这个阶段说的是在各个服务中执行实际的操作。
Cancel 阶段:如果任何一个服务的业务方法执行出错,那么这里就需要进行补偿,就是执行已经执行成功的业务逻辑的回滚操作。(把那些执行成功的回滚)
这种方案说实话几乎很少人使用,我们用的也比较少,但是也有使用的场景。因为这个事务回滚实际上是严重依赖于你自己写代码来回滚和补偿了,会造成补偿代码巨大,非常之恶心。

比如说我们,一般来说跟钱相关的,跟钱打交道的,支付、交易相关的场景,我们会用 TCC,严格保证分布式事务要么全部成功,要么全部自动回滚,严格保证资金的正确性,保证在资金上不会出现问题。

而且最好是你的各个业务执行的时间都比较短。

但是说实话,一般尽量别这么搞,自己手写回滚逻辑,或者是补偿逻辑,实在太恶心了,那个业务代码很难维护。


本地消息表
本地消息表其实是国外的 ebay 搞出来的这么一套思想。

这个大概意思是这样的:

A 系统在自己本地一个事务里操作同时,插入一条数据到消息表;
接着 A 系统将这个消息发送到 MQ 中去;
B 系统接收到消息之后,在一个事务里,往自己本地消息表里插入一条数据,同时执行其他的业务操作,如果这个消息已经被处理过了,那么此时这个事务会回滚,这样保证不会重复处理消息;
B 系统执行成功之后,就会更新自己本地消息表的状态以及 A 系统消息表的状态;
如果 B 系统处理失败了,那么就不会更新消息表状态,那么此时 A 系统会定时扫描自己的消息表,如果有未处理的消息,会再次发送到 MQ 中去,让 B 再次处理;
这个方案保证了最终一致性,哪怕 B 事务失败了,但是 A 会不断重发消息,直到 B 那边成功为止。
这个方案说实话最大的问题就在于严重依赖于数据库的消息表来管理事务啥的,会导致如果是高并发场景咋办呢?咋扩展呢?所以一般确实很少用。
1月7
今天使用RequestBody接受前端传过来的参数,以前接受字符串数组非常成功,这次把形参改成了List,原本以为顺利接受参数并映射成User的list结构,结果竟然在我取user.getId()时报了com.alibaba.fastjson.JSONObject cannot be cast to xxx的错。

后端:
@RequestMapping("/insertUser")
public void insertBlank(@RequestBody List userList) {
     User user = userList.get(0);
     System.out.println(user.getId());
}


我的user对象没有转换成功,还是一个一个JSONObject,但是请观察,JSONArray转换成了ArrayList。

  嗯,配置的映射转换器生效了,结果表明,RequestBody能直接将json对象映射成java对象,但仅限于第一层的对象,至于嵌套的对象,则需要开发者自己去转换。

@RequestMapping("/insertUser")
public void insertUser(@RequestBody List list) {
    List userList = list.stream().map(json -> JSONObject.toJavaObject(json, User.class)).collect(Collectors.toList());
   service.insertUser(userList);
}
12月30
在弹出窗口里刚开始不管点击什么都无法显示,后来点击表情的时候发现表情的选项框出现在了当前dialog的后面
然后猜测所有的选项框点击后,都出现在dialog的后面。
接着开始F12,发现当前dialog的z-index的值是1005。
返回看ueditor的z-index。

在ueditor.config.js里zIndex的默认值是900;将值改为1100
强行刷新页面,或者打开ueditor.config.js强刷,然就成功!
12月20
首先从以下几点来介绍:
1.为什么要使用synchronized

在并发编程中存在线程安全问题,主要原因有:1.存在共享数据 2.多线程共同操作共享数据。关键字synchronized可以保证在同一时刻,只有一个线程可以执行某个方法或某个代码块,同时synchronized可以保证一个线程的变化可见(可见性),即可以代替volatile。

2.实现原理

synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性

3.synchronized的三种应用方式

Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:

普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁
静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁
同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
4.synchronized的作用

Synchronized是Java中解决并发问题的一种最常用最简单的方法 ,他可以确保线程互斥的访问同步代码
12月19
在tomcat启动时报invalid LOC header (bad signature)错误,这个问题真是搞死人啊,原来是一个jar的问题,删除让maven重新下载就好了,搞了我半天。

Caused by: java.lang.IllegalArgumentException: java.util.zip.ZipException: invalid LOC header (bad signature)  
    at org.apache.catalina.webresources.AbstractSingleArchiveResourceSet.initInternal(AbstractSingleArchiveResourceSet.java:142)  
    at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:102)  
    ... 12 more  
Caused by: java.util.zip.ZipException: invalid LOC header (bad signature)  
    at java.util.zip.ZipFile.read(Native Method)  
    at java.util.zip.ZipFile.access$1400(ZipFile.java:60)  
    at java.util.zip.ZipFile$ZipFileInputStream.read(ZipFile.java:734)  
    at java.util.zip.ZipFile$ZipFileInflaterInputStream.fill(ZipFile.java:434)  
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)  
    at sun.misc.IOUtils.readFully(IOUtils.java:65)  
    at java.util.jar.JarFile.getBytes(JarFile.java:425)  
    at java.util.jar.JarFile.getManifestFromReference(JarFile.java:193)  
    at java.util.jar.JarFile.getManifest(JarFile.java:180)  
    at org.apache.catalina.webresources.AbstractSingleArchiveResourceSet.initInternal(AbstractSingleArchiveResourceSet.java:140)  
    ... 13 more  

下面是用于定位哪个jar文件没正常被加载的

点击在新窗口中浏览此图片
10月31

常用MySQL集群解决方案

10:39数据库  From: 本站原创
1、mysql企业常用集群架构
点击在新窗口中浏览此图片

在中小型互联网的企业中。mysql的集群一般就是上图的架构。WEB节点读取数据库的时候读取dbproxy服务器。dbproxy服务器通过对SQL语句的判断来进行数据库的读写分离。读请求负载到从库(也可以把主库加上),写请求写主库。

这里的dbproxy是数据库集群的唯一出口所以也需要做高可用。

drproxy是数据库读写分离的常用软件,amoeba、mycat、cobar也很常用。这类软件不仅带有读写分离功能,还可以实现负载均衡以及后端节点的健康检查。

数据库的读写分离除了通过这类数据库中间件软件实现,还可以写在程序中。

通常我们的主库要做双主高可用,实现主库挂掉另一个主库立刻接管。如果不做双主,从库接管主库的时候需要做状态迁移,会有延迟。

数据库主库的高可用重点需要考虑的是数据同步。比较常用的高可用方案有:

1、keepalived+mysql replication。通过keepalived实现VIP飘逸,通过mysql自带的同步方案replication实现数据同步。

2、hearbeat+drbd。通过drbd实现双主数据的同步,这个数据同步是基于块设备的。比一般的同步方案要快很多。通过heartbeat实现VIP漂移以及drbd资源的切换管理。

3、keepalived+mha。

对于从库,最好不要超过5个。我们可以把其中的三个作为用户访问的节点,把另外一个作为内部人员的查询节点。因为内部人员查询节点的时候一般是按照时间段查询,不经过索引,占用的资源比较多,所以要把这个节点单独专用,以免影响客户访问。最后我们应该留一个从库进行数据库的数据备份。

从库的数据一致性保持可以通过直接于主库进行主从辅助,也可以从其他从库那进行主从复制(优点是减少主库压力,缺点是延迟稍大)。

2、MYSQL数据架构
数据库服务器==》数据库(多个实例)==》多个库==》多个表==》多个字段行列(数据)

在一台数据库服务器上可以跑多个实例,一个实例中有多个库,一个库有多个表,一个表有多个行列。
10月26
Nginx作为一个轻量级的HTTP服务器,相比Apache优势也是比较明显的,在性能上它占用资源少,能支持更高更多的并发连接,从而达到提高访问效率;在功能上它是一款非常优秀的代理服务器与负载均衡服务器;在安装配置上它安装,配置都比较简单
Nginx优化配置详解
但在实际的生产配置环境中,肯定会经常遇到需要修改、或者重新增加Nginx配置的问题,有的时候需求更是多种多样,修修改改经常会出现这样、那样的一些错误,特别的烦索。
基于以上的原因,肯定很多读者伙伴经常会收集一些配置文档、或者电脑里也保存着一些自己日常的常用配置案例,但是终究还是不是很便利。今天,民工哥给大家介绍一款「超级牛掰的神器」,可以在线一键生成Nginx的配置。
点击在新窗口中浏览此图片

网址:https://nginxconfig.io/
NGINX Config 支持 HTTP、HTTPS、PHP、Python、Node.js、WordPress、Drupal、缓存、逆向代理、日志等各种配置选项。在线生成 Web 服务器 Nginx 配置文件。
10月26
其实我们大家做产品意见反馈模块的时候可以找一个有没有同类型直接用的产品接入进来就可以了, 没有必要自己重复造轮子,做的体验不好,又浪费时间,不如使用成型的产品,不过有个问题,可以这种成型的产品可能某一天就下线了,这个可能需要自己去权衡了。

比如我们可以使用腾讯的吐个槽:https://tucao.qq.com/
点击在新窗口中浏览此图片





分页: 2/51 第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]