Arganzheng's Blog

stay hungry, stay foolish

如何实现一个配置中心

问题 服务一般有很多依赖配置,例如访问数据库有连接字符串配置,连接池大小和连接超时配置,这些配置在不同环境(开发/测试/生产)一般不同,比如生产环境需要配连接池,而开发测试环境可能不配,另外有些参数配置在运行期可能还要动态调整,例如,运行时根据流量状况动态调整限流和熔断阀值。 传统配置文件方式虽然把配置项分离到单独的配置文件,但是修改一个配置项,需要提交版本管理,发布,重启。整个过程比较麻烦,特别是发布多台机器。整个配置上线流程跟修改代码没有太大区别。不利于集中式管理和动态调整。 解决方案 目前比较常见的做法是搭建一个运行时配置中心支持动态配置,简化架构如下图所示: 动态配置存放在集中的配置服务器上,用户通过管理界面配置和调整服务配置,具体服务通过定期...

如何单元测试二方库

问题 为了模块化,我们需要将通用的模块拆分出来,作为一个单独的二方库,在多个工程中引用。比如product-biz, product-dataaccess等。这些模块一般会使用到其他框架,比如Spring,mybatis,并且可能还有一些配置项根据不同的工程有不同的配置,所有这些依赖(配置文件和配置项)一般都是在引用方提供,然后整个工程才能够跑起来。这样会带来一个严重的问题,就是这些二方库不具有自治性。他们的代码和配置是分离的,而没有配置,单元测试也没法跑起来。 解决方案 要让单元测试可以run起来,配置是必须提供的,包括框架需要的配置,比如Spring的bean配置,mybatis配置,还有相关的配置项。这样该二方库就是自治的了。他依赖的东西都可以到位,为他...

JS跨域问题及解决方案

问题 Same-origin policy Same-origin policy(SOP): 只有当两个资源同源的时候,浏览器才允许他们之间的脚本互相访问,包括请求各自的服务端,修改DOM结构和读取cookies,localStorage等。 源(origin): 一个页面的源(origin)是由三部分(triple)组成的 {protocol, host, port}。 当且只当这个三元组的值完全相同的时候,两个资源才被认为是同源的。 SOP可以防止恶意脚本读取你的信息(比如cookies信息)然后发送到他们的服务器,增加了安全性。 NOTES 二级域名不同也是跨域。 解决方案 1. Cross Origin Resource Sharing C...

Java8时间处理

用Java处理过时间的基本都会有一个感觉,就是麻烦,甚至恶心。 老的Java 时间API的核心类和方法比较少,如下: System.currentTimeMillis(): static method that returns the current date and time as milliseconds since January 1st 1970. java.util.Date: 表示一个特定的时间,精度是毫秒(millisecond)。很多方法都是deprecated.. java.sql.Date: 表示一个日期,不包含时间信息,定位是用于JDBC,但是实际上基本不用。。 java.sql.Timestamp: 继承java.uti...

input too large for RSA cipher

自从我们的某些接口用上加密解密后,总是会收到如下错误报警: 2015-10-22 16:41:23,453 [WARN] [catalina-exec-178] me.arganzheng.study.nantianmen.utils.ParamsHelper (ParamsHelper.java:132): Can not get decrypted params. encryptedParams=3ekss73ymx96en5vrrai58ux8ibifleidyayo2ewpry09sk0/v42cgs8cvquevbqvb/ecmnfyluxgw8ybu1sk2a w9edu1titloweefeehbcant3xtiqytckh2bdsadz4jvmj...

MIME和编码学习笔记

Base64 所谓Base64,就是说从ASCII码中选出64个字符—-大写字母A-Z、小写字母a-z、数字0-9、符号”+”、”/”(再加上作为填充字符的”=”,实际上是65个字符),作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。 具体来说,转换方式可以分为四步: 将每3个字节作为一组,一共是24个二进制位: 3x8=24 将这24个二进制位分为4组,每个组有6个二进制位: 24/4=6 在每组前面加两个00,扩展成32个二进制位,即3个字节: 4x(6+2)=32 根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值 说明 因为转换后的每个字符的最高两位都是0,所以实际有效位数是6位,也就是...

分布式文件系统选型和预研

背景 候选DFS MooseFS FastDFS TFS Hi all, 背景 我们目前有接近3.5kw的文件数,总体容量是800GB的样子,平均文件大小是二三十KB的样子。主要是图片、HTML文件等小文件。走CDN之后,QPS大概是二三十的样子。目前我们的静态资源是部署在BPC的私有云平台NFS上。该平台主要是支持大文件,对单机文件数量有比较大的限制(单机100w,我们现在已经调高到了单机300w的样子),因此对机器数目的要求比较高(OP为我们投入了40台机器,目前的使用率已经到达86.5%),跟NFS的同学沟通是目前的机器数最多只能支撑到8kw,建议我们加机器或者定期归档老文件。 我们现在只保留了一个月的新闻,未来的业务规划可能会保留一...

MySQL主从同步学习

原理 如下图所示: Master将binlog推送给每个连接上来的slave Slave的IO线程将Master发送过来的binlog写入到本地的Relay log日志文件 Slave的SQL线程读取relay log日志,apply里面的变更 具体可以参见:How does MySQL Replication really work?,非常深入浅出的一篇文章。 说明 1、MySQL5.5版本开始支持半同步复制 2、ORACLE MySQL 5.6版本又引入GTID(Global Transactions Identifier)、多线程复制: GTID: 在MySQL5.6以前对于主从复制出现问题有时候需要你分析BINLOG找...

Quartz的misfire机制

Quartz在如下情况下可能没有办法按时执行job: 所有的worker线程都处于忙碌状态(可能在执行更高优先级的任务) Quartz scheduler挂掉了 这个任务的开始执行时间就是在过去(可能是创建时候配置错了) org.quartz.jobStore.misfireThreshold (in milliseconds), 默认是60000ms(也就是1min). 这也是Quartz支持秒级别精确调度的一个体现,超过1分钟没有执行的任务就被认为是misfired。It defines how late the trigger should be to be considered misfired. 如果有任务超过了org.quartz.j...

如何让一个Quartz实例不执行任务

Quartz默认的集群方式每个节点(实例)都是对等,都可以创建任务,都会去抢任务。但是有时候我们希望能够有不对等的结构,比如运营后台提供友好的界面管理任务,然后有一些肉机,专门执行任务。这样的好处,任务不会影响到管理后台,管理后台的发布也不会中断执行中的任务。 谷歌和翻看官方文档都没有发现这个配置,只能查看源码了。最后发现有一个类看起来就是为这个实现的: package org.quartz.simpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.quartz.SchedulerConfigException; import org.quartz.spi.Thread...

×