搭车

开源的电子邮件模板

开源的电子邮件模板,质量相当的高.网址: https://www.sendwithus.com/resources/templates 

Web应用的缓存设计模式

from: http://robbinfan.com/blog/38/orm-cache-sumupORM缓存引言从10年前的2003年开始,在Web应用领域,ORM(对象-关系映射)框架就开始逐渐普及,并且流行开来,其中最广为人知的就是Java的开源ORM框架Hibernate,后来Hibernate也成为了EJB3的实现框架;2005年以后,ORM开始普及到其他编程语言领域,其中最有名气的是Ruby on rails框架的ORM - ActiveRecord。如今各种开源框架的ORM,乃至ODM(对象-文档关系映射,用在访问NoSQLDB)层出不穷,功能都十分强大,也很普及。然而围绕ORM的性能问题,也一直有很多批评的声音。其实ORM的架构对插入缓存技术是非常容易的,我做的很多项目和产品,但凡使用ORM,缓存都是标配,性能都非常好。而且我发现业界使用ORM的案例都忽视了缓存的运用,或者说没有意识到ORM缓存可以带来巨大的性能提升。ORM缓存应用案例我们去年有一个老产品重写的项目,这个产品有超过10年历史了,数据库的数据量很大,多个表都是上千万条记录,最大的表记录达到了9000万条,Web访问的请求数每天有300万左右。老产品采用了传统的解决性能问题的方案:Web层采用了动态页面静态化技术,超过一定时间的文章生成静态HTML文件;对数据库进行分库分表,按年拆表。动态页面静态化和分库分表是应对大访问量和大数据量的常规手段,本身也有效。但它的缺点也很多,比方说增加了代码复杂度和维护难度,跨库运算的困难等等,这个产品的代码维护历来非常困难,导致bug很多。进行产品重写的时候,我们放弃了动态页面静态化,采用了纯动态网页;放弃了分库分表,直接操作千万级,乃至近亿条记录的大表进行SQL查询;也没有采取读写分离技术,全部查询都是在单台主数据库上进行;数据库访问全部使用ActiveRecord,进行了大量的ORM缓存。上线以后的效果非常好:单台MySQL数据库服务器CPU的IO Wait低于5%;用单台1U服务器2颗4核至强CPU已经可以轻松支持每天350万动态请求量;最重要的是,插入缓存并不需要代码增加多少复杂度,可维护性非常好。总之,采用ORM缓存是Web应用提升性能一种有效的思路,这种思路和传统的提升性能的解决方案有很大的不同,但它在很多应用场景(包括高度动态化的SNS类型应用)非常有效,而且不会显著增加代码复杂度,所以这也是我自己一直偏爱的方式。因此我一直很想写篇文章,结合示例代码介绍ORM缓存的编程技巧。今年春节前后,我开发自己的个人网站项目,有意识的大量使用了ORM缓存技巧。对一个没多少访问量的个人站点来说,有些过度设计了,但我也想借这个机会把常用的ORM缓存设计模式写成示例代码,提供给大家参考。我的个人网站源代码是开源的,托管在github上:robbin_siteORM缓存的基本理念我在2007年的时候写过一篇文章,分析ORM缓存的理念:ORM对象缓存探讨 ,所以这篇文章不展开详谈了,总结来说,ORM缓存的基本理念是:以减少数据库服务器磁盘IO为最终目的,而不是减少发送到数据库的SQL条数。实际上使用ORM,会显著增加SQL条数,有时候会成倍增加SQL。数据库schema设计的取向是尽量设计 细颗粒度 的表,表和表之间用外键关联,颗粒度越细,缓存对象的单位越小,缓存的应用场景越广泛尽量避免多表关联查询,尽量拆成多个表单独的主键查询,尽量多制造 n + 1 条查询,不要害怕“臭名昭著”的 n + 1 问题,实际上 n + 1 才能有效利用ORM缓存利用表关联实现透明的对象缓存在设计数据库的schema的时候,设计多个细颗粒度的表,用外键关联起来。当通过ORM访问关联对象的时候,ORM框架会将关联对象的访问转化成用主键查询关联表,发送 n + 1条SQL。而基于主键的查询可以直接利用对象缓存。我们自己开发了一个基于ActiveRecord封装的对象缓存框架:second_level_cache ,从这个ruby插件的名称就可以看出,实现借鉴了Hibernate的二级缓存实现。这个对象缓存的配置和使用,可以看我写的ActiveRecord对象缓存配置 。下面用一个实际例子来演示一下对象缓存起到的作用:访问我个人站点的首页。 这个页面的数据需要读取三张表:blogs表获取文章信息,blog_contents表获取文章内容,accounts表获取作者信息。三张表的model定义片段如下,完整代码请看models :class Account < ActiveRecord::Base acts_as_cached has_many :blogsendclass Blog < ActiveRecord::Base acts_as_cached belongs_to :blog_content, :dependent => :destroy belongs_to :account, :counter_cache => trueendclass BlogContent < ActiveRecord::Base acts_as_cachedend传统的做法是发送一条三表关联的查询语句,类似这样的:SELECT blogs.*, blog_contents.content, account.name FROM blogs LEFT JOIN blog_contents ON blogs.blog_content_id = blog_contents.id LEFT JOIN accounts ON blogs.account_id = account.id往往单条SQL语句就搞定了,但是复杂SQL的带来的表扫描范围可能比较大,造成的数据库服务器磁盘IO会高很多,数据库实际IO负载往往无法得到有效缓解。我的做法如下,完整代码请看home.rb :@blogs = Blog.order('id DESC').page(params[:page])这是一条分页查询,实际发送的SQL如下:SELECT * FROM blogs ORDER BY id DESC LIMIT 20转成了单表查询,磁盘IO会小很多。至于文章内容,则是通过blog.content的对象访问获得的,由于首页抓取20篇文章,所以实际上会多出来20条主键查询SQL访问blog_contents表。就像下面这样:DEBUG - BlogContent Load (0.3ms) SELECT `blog_contents`.* FROM `blog_contents` WHERE `blog_contents`.`id` = 29 LIMIT 1DEBUG - BlogContent Load (0.2ms) SELECT `blog_contents`.*…

GistBox 代码管理工具

GistBox 提供一种漂亮的方式来组织代码片段。将你的库保存到云端进行备份,再也不用担心丢失。GistBox采用标准的HTML5技术构建。GistBox使用GitHub的后端,但增加了自己的标签和搜索功能层。使用Github账号登陆Gistbox可以将你的代码直接同步进来,反过来,你在GB上的所有改动也都会同步到Github上;GistBox的结构设 计清晰,从左至右分别是主导航(新建Gist,Gists入口,收藏入口-Labels)、Gists列表(Public/Private)、具体代码 区,亲们可以用Label给代码加上各种分辨标签,方便分类整理,在检索代码时可以用顶部的搜索栏,输入关键词或Label可以更快的搜索到目标代码。网址: http://www.gistboxapp.com/

ManicTime版本更新,有中文版了

ManicTime是一款数据收集软件,装在您的计算机上可以很准确的计算出你做每一项事情所花的时间 ,也可以计算出你离开的时间,比如,你离开计算机出去吃饭了,你离开多久,它就能计算出多久,使用起来很方便。ManicTime很早就知道,因为没有中文版,而且这东西比较占内容,就一直没用。前段时间装系统了之后,想统计一下自己的电脑使用情况,就装上了,用了几个月,一次电脑恢复了系统,没有备份数据,之前的数据都没有了,杯具啊!这次是从9月份开始用的,用到现在,基本上隔一段时间就做一次数据备份,数据很重要。今天电脑开始,就出现有新版本的升级提醒,就update了,完毕之后,高兴了,有中文版了看得舒服的了。汉字,喜欢的很啊下载地址http://www.manictime.com/

祝爷爷寿比南山

祝爷爷寿比南山爷爷刚刚过寿,先祝爷爷寿比南山啊!身体健康,高高兴兴就好。我的弟弟妹妹们都回家了,就我在外面。看着爷爷过寿的相片,一家人团团圆圆的,真是幸福啊!

难道真的就要地震了。。。

难道真的就要地震了。。。

webservice中的xml文件的交互

  使用webservice中使用的类型可以是好多种,string、element、document等等甚至可以使对象!  我使用element来传输xml文件,写了一个文件,源码如下import java.io.Reader;import java.io.StringReader;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.HashMap;import java.util.Map;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import org.apache.xpath.XPathAPI;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.xml.sax.InputSource;/**工单查询接口 boos提供serialNumber、serviceNum输入参数@author joypen */public class WidebandBusinessQueryService { // 提供的查询方法 public Element queryWideband(Element requestXml) throws Exception { Map map = this.databaseMethod(requestXml); String responseXml = this.dealResponseXml(map); System.out.println("111 "+responseXml); Document doc = null; Reader strreader=new StringReader(responseXml); DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); doc = builder.parse(new InputSource(strreader)); return doc.getDocumentElement(); } // 连接数据库,并且执行sql语句 private Map databaseMethod(Element requestXml) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; Map map = null; String serialNumber = null; String serviceNum = null; try { map = this.parseXml(requestXml); serialNumber = (String) map.get("SERIALNUMBER"); serviceNum = (String) map.get("SERVICENUM"); if(TextUtil.isNull(serialNumber) || "".equals(serialNumber) || TextUtil.isNull(serviceNum) || "".equals(serviceNum)){ map.put("ERRORCODE", "1"); map.put("DESCRIPTION", "SERIALNUMBER OR SERVICENUM IS WORING!"); }else{ conn = Helper.getDBCnn(); conn.setAutoCommit(false); String sqlString = this.sqlQueryString(serialNumber, serviceNum); ps = conn.prepareStatement(sqlString); rs = ps.executeQuery(); map = this.dealResult(rs); } } catch (Exception e) { System.out.print("WidebandBusinessQueryService--数据库连接出错!"); e.printStackTrace(); }finally{ try { rs =…

Eclipse快捷键

Ctrl+1 快速修复(最经典的快捷键,就不用多说了)Ctrl+D: 删除当前行Ctrl+Alt+↓ 复制当前行到下一行(复制增加)Ctrl+Alt+↑ 复制当前行到上一行(复制增加)Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)Alt+↑ 当前行和上面一行交互位置(同上)Alt+← 前一个编辑的页面Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)Shift+Ctrl+Enter 在当前行插入空行(原理同上条)Ctrl+Q 定位到最后编辑的地方Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)Ctrl+M 最大化当前的Edit或View (再按则反之)Ctrl+/ 注释当前行,再按则取消注释Ctrl+O 快速显示 OutLineCtrl+T 快速显示当前类的继承结构Ctrl+W 关闭当前EditerCtrl+K 参照选中的Word快速定位到下一个Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)Ctrl+/(小键盘) 折叠当前类中的所有代码Ctrl+&times;(小键盘) 展开当前类中的所有代码Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)Ctrl+Shift+F4 关闭所有打开的EditerCtrl+Shift+X 把当前选中的文本全部变味小写Ctrl+Shift+Y 把当前选中的文本全部变为小写Ctrl+Shift+F 格式化当前代码Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift开头的了)Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)Alt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)Alt+Shift+I 合并变量(可能这样说有点不妥Inline)Alt+Shift+V 移动函数和变量(不怎么常用)Alt+Shift+Z 重构的后悔药(Undo)编辑作用域 功能 快捷键全局 查找并替换 Ctrl+F文本编辑器 查找上一个 Ctrl+Shift+K文本编辑器 查找下一个 Ctrl+K全局 撤销 Ctrl+Z全局 复制 Ctrl+C全局 恢复上一个选择 Alt+Shift+↓全局 剪切 Ctrl+X全局 快速修正 Ctrl1+1全局 内容辅助 Alt+/全局 全部选中 Ctrl+A全局 删除 Delete全局 上下文信息 Alt+?Alt+Shift+?Ctrl+Shift+SpaceJava编辑器 显示工具提示描述 F2Java编辑器 选择封装元素 Alt+Shift+↑Java编辑器 选择上一个元素 Alt+Shift+←Java编辑器 选择下一个元素 Alt+Shift+→文本编辑器 增量查找 Ctrl+J文本编辑器 增量逆向查找 Ctrl+Shift+J全局 粘贴 Ctrl+V全局 重做 Ctrl+Y查看作用域 功能 快捷键全局 放大 Ctrl+=全局 缩小 Ctrl+-窗口作用域 功能 快捷键全局 激活编辑器 F12全局 切换编辑器 Ctrl+Shift+W全局 上一个编辑器 Ctrl+Shift+F6全局 上一个视图 Ctrl+Shift+F7全局 上一个透视图 Ctrl+Shift+F8全局 下一个编辑器 Ctrl+F6全局 下一个视图 Ctrl+F7全局 下一个透视图 Ctrl+F8文本编辑器 显示标尺上下文菜单 Ctrl+W全局 显示视图菜单 Ctrl+F10全局 显示系统菜单 Alt+-导航作用域 功能 快捷键Java编辑器 打开结构 Ctrl+F3全局 打开类型 Ctrl+Shift+T全局 打开类型层次结构 F4全局 打开声明 F3全局 打开外部javadoc Shift+F2全局 打开资源 Ctrl+Shift+R全局 后退历史记录 Alt+←全局 前进历史记录 Alt+→全局 上一个 Ctrl+,全局 下一个 Ctrl+.Java编辑器 显示大纲 Ctrl+O全局 在层次结构中打开类型 Ctrl+Shift+H全局 转至匹配的括号…

头像的变化

  看到网上有脸皮的一个网站,进去可以自己定义自己的卡通头像,随手做了一个,做完之后,可以产生一套表情图片,挺不错的,自己也修改了一下,顺便改了一下QQ头像, 特点就是有个红鼻子。因为如果要扮演一个小丑的话,红鼻子肯定少不了的,虽然我没打算扮演小丑,但小丑很可爱的啊!反正是卡通的,没必要太逼真吧!

卸掉IE8,降级使用

IE8的正式版出来了,从一开始出现IE8的下载就在使用,IE好用着,但是好多网站都还不支持,网站的框架结构不是都会变形,gamil也没支持,很不好用。狠心了一下,卸载了IE8了。