记录2个有趣的词语

记录2个有趣的词语:康波,睡后收入。

发表在 生活笔记 | Comments Off on 记录2个有趣的词语

h2database学习(二):executeQuery的生命周期(下)

这里主要讲数据的获取,先看一张简图

一次查询,客户端总共发起3次请求,分别是请求建立连接(A),请求传入sql预编译(B),执行查询(C)。

服务端:

收到A请求后,初始化Session,DB,Table,Index,Page。其中包含读db文件取到meta信息和真实数据,加载到内存。如果数据量小,比如我测试只有2条数据,作为Root的Page,已经把这2条记录加载到其内部的成员变量Object[] keys,Object[] values了,在后面接收到C请求后,不会再有读磁盘的IO操作。

收到B请求后,解析sql语句,什么表,有哪几列,生成DML指令缓存起来并返回给客户端。

收到C请求后,遍历索引,从Page里取出数据封装成RowImpl,返回给客户端。

整理几个常见的类的依赖关系,便于理解代码。
继续阅读

发表在 数据库 | 标签为 , | Comments Off on h2database学习(二):executeQuery的生命周期(下)

h2database学习(一):executeQuery的生命周期(上)

从 https://github.com/h2database/h2database 拉代码到本地,找到org.h2.tools.Server,直接运行main()方法,控制台输出如下:

TCP server running at tcp://192.168.0.104:9092 (only local connections)
PG server running at pg://192.168.0.104:5435 (only local connections)
Web Console server running at http://192.168.0.104:8082 (only local connections)
表示数据库已经成功起来了。如果服务端和客户端不是同一台机器,则服务端启动时需要加上启动参数-tcpAllowOthers以便允许其他机器的客户端访问。

然后找到org.h2.samples.HelloWorld,运行main()方法,控制台输出:
Hello

客户端运行完毕。

客户端connection的产生:

Transfer就是客户端与服务端建立的一个连接包装器,用来进行数据的读写。
继续阅读

发表在 数据库 | 标签为 , | Comments Off on h2database学习(一):executeQuery的生命周期(上)

学习数据库前言

去年拉了lealone代码,看了一部分,后来琐事多,再加上没能严格要求自己,学习就中断了,这一放纵就是半年。后来偶尔也有看这看那,但是看的东西不能够沉淀成文字输出出来,基本也只能算是浅尝辄止。学习,贵在坚持。
后面打算学习数据库方面的东西。

由于本人擅长java语言,网上找了下,纯java写的开源数据库也不少。

Lealone:https://github.com/lealone/Lealone

h2database:https://github.com/h2database/h2database

derby:https://github.com/apache/derby

hbase:https://github.com/apache/hbase

Cassandra:https://github.com/apache/cassandra

以后可能就围着上面这几个项目学习了,希望自己能够坚持下去。

BTW:以前说到的数据库中间件cobar(https://github.com/alibaba/cobar)也有看,但是感觉,在应用和数据库之间的这层proxy还是简单点好,至少可以保证功能完整,出了问题也好排查,实在不行在一个库里多建几张表,你说呢。

发表在 数据库 | 标签为 , , , , | Comments Off on 学习数据库前言

Lealone学习(一):简介和QuickStart

Lealone是什么?(发音:把萝莉倒过来念,莉萝)

引用官方描述:
Lealone是一个兼具RDBMS、NoSQL优点的面向OLTP场景的分布式关系数据库。

官方地址:https://github.com/lealone/Lealone。

具有以下特点:

开源版本(不支持分布式)

完全异步化,使用少量线程就能处理大量并发
基于SQL优先级的抢占式调度,慢查询不会长期霸占CPU
创建JDBC连接非常快速,占用资源少,不再需要JDBC连接池
插件化存储引擎架构,内置MVStore存储引擎
插件化事务引擎架构,事务处理逻辑与存储分离
支持索引、视图、Join、子查询、触发器、自定义函数、Order By、Group By、聚合
从H2数据库借鉴了大量成熟的代码和思想

从源代码里盗来一张架构图,先看下它的设计(其中Pluggable部分都是可扩展的):

架构图
继续阅读

发表在 数据库 | 标签为 , | Comments Off on Lealone学习(一):简介和QuickStart

这三个月都忙了些啥

今天,一朋友突然问我,博客怎么不更新了,我打开博客一看,确实,近三个月都没写什么,这三个月都忙了些啥。

话说时间过得真快,一晃三个月就过去了。七八月的时候,工作比较忙,晚上回来的较晚,记得有时会看下Lealone源代码,地址:https://github.com/lealone/Lealone,微博上某个大神用java写的单机版数据库,据说分布式版本是商业版,没有开源。代码里面又涉及到lambda表达式,又看了下java8的新特性,还用到了Vert.x框架,该框架据说和springBoot一样受欢迎,官网地址:http://vertx.io,我自己也还没入坑。九月,杭州G20放假,跟老婆出去旅游玩了几天,九月20号,科目二考试,前几个周末也是在练车,新房子从今年三月装修至今,接近尾声了,由于是半包,基本每个周末都会逛建材市场,或者去新房子里监工或验收。前几天十一放假回家,老婆吐的厉害,去医院检查,原来怀孕了,喜出望外,同时也有些担心,因为我们经常往新房子里跑,甲醛估计也吸了一些,不知对胎儿是否有影响,还好每次去新房子里呆的时间都不长,并且窗户和门都开着。现在,每天还得早点睡觉,孕妇得早点休息,昨晚睡觉前还进行胎教,念故事《小蝌蚪找妈妈》,偶尔下班了还得买点菜,给老婆补补营养。天天对着宝宝树app,看着上面写的胎儿每天的变化,期待新一天的到来。

技术学习是荒废了几个月了,后面希望能够挤出时间,把落下的博客补上来。

发表在 生活笔记 | Comments Off on 这三个月都忙了些啥

学习数据访问层中间件前言

最近打算找个开源的数据访问层中间件学习下,网上搜了一下,有Tddl,Cobar,Mycat等,有点乱花渐欲迷人眼的赶脚,Tddl是淘宝出的,据说只开源了部分功能,而且对内部系统比较依赖。Cobar看官网介绍,在阿里巴巴也经历过了一段时间的考验,代码和文档还算完整,最近没有什么更新。Mycat,基于Cobar开发,目前文档较多,更新较活跃。

3个项目地址如下:

tddl:https://github.com/alibaba/tb_tddl
cobar:https://github.com/alibaba/cobar
mycat:https://github.com/MyCATApache

其他还有收费的,例如平民软件OneProxy。

记得在曾宪杰写的《大型网站系统与Java中间件实践》一书背后封面的名家力荐里,林昊指出了构建大型Java网站必备的三大利器—服务框架、消息中间件和数据访问层。服务框架Dubbo以前搞过,消息中间件Rocketmq去年断断续续写过一些文章,数据访问层还没有学习过,今年打算学习下。

打算先学习下Cobar。原因是项目拉下来瞅了几眼,分包模块清晰,代码工整。再有就是,在cobar-server的pom依赖只配置了log4j和junit,也就是说,Cobar的server端代码全部都是使用原生jdk编写的,可见原作者内功还是很深厚的,钦佩。最后,Cobar和Dubbo都是一个时期(2011-2013)的经典框架,大约出来时间都是2011年,都是在阿里巴巴运行2,3年,记得当时官网还是http://code.alibabatech.com/,Dubbo写的是日处理2亿次rpc请求,而这里Cobar写的是集群日处理在线SQL请求50亿次以上,说明他们都还比较成熟。

当然,其他2个项目也都是值得学习的。

发表在 编程语言 | 标签为 , | Comments Off on 学习数据访问层中间件前言

扩展webx资源装载器之HttpResourceLoader(一):简单实现

webx是一个开源的web框架,主页地址:http://www.openwebx.org/。这里我们主要说下使用http协议对网络中任意资源进行装载,来增强webx资源装载的功能。

用webx官网的mvn命令,生成tutorial1项目,里面webx的pom如下:

        ...
       <webx-version>3.2.4</webx-version>
        ...
        <dependency>
            <groupId>com.alibaba.citrus</groupId>
            <artifactId>citrus-webx-all</artifactId>
        </dependency>
        ...

这个版本里,webx的resourceLoader有2种扩展:

[res-loaders:webapp-loader /]:通过servletContext.getResource(resourceName)来获取资源。
[res-loaders:classpath-loader /]:通过classLoader.getResource(resourceName)来获取资源。
[res-loaders:super-loader/]:通过resource.xml里配置的资源别名,结合配置的资源加载器,来进行资源加载。这种是在前面2种的基础之上。

基于springExt,这里扩展点是res-loaders,捐献是webapp-loader,classpath-loader和super-loader。

新增一个http-loader,即[res-loaders:http-loader/],具体的捐献实现和配置在后面会再进行介绍,。

HttpResourceLoader简单类实现:
继续阅读

发表在 编程语言 | 标签为 , | Comments Off on 扩展webx资源装载器之HttpResourceLoader(一):简单实现

2015年年度总结

2015年上半年用2个字概括:平淡,下半年用2个字概括,忙碌。

2015上半年,平平淡淡,一晃就过去了,到下半年,六月份到八月份,回了老家2次,年假差不多用完了(湖北离杭州还是蛮远的),期间感冒了引发鼻炎,拖了好久,后来去浙二医院都去了2次。

八九月份,开始看房,一共也就看了3个地方就定下来了,九月份开始牙痛,又去看牙,去了六七趟,然后医生说还要把里面的智齿拔了,不然不好治,心里害怕了好久,拖到十一月终于把智齿拔了。

十月十一月十二月开始办理房子各种手续,各种签名按手印,期间也去拍了婚纱照,去了2次都下雨,勉强把外景拍完,今天去取了相册。

今年除了事情多,比较忙碌外,还给我最大的感觉就是转变,生活角色的转变,生活状态的转变,以前下了班或者周末,写写代码,打打dota,时间充裕,现在结了婚,繁琐的事情多了起来,自己的时间很琐碎,github今年也没提交什么代码,博客也一个月只有一篇。当然,这跟我没有利用好琐碎的时间有很大的关系。

工作上,简单来说,日常工作都还完成的不错,拿了个部门半年的技术达人奖,期待自己能够再接再厉,明年能有所突破。

2016年目标:

1.工作上,除了code,提高自己其他方面的能力,得到他人的认可。
2.保持博客的更新频率,做到一个月更新3篇左右,目前博客进3个月日均pv是45,期待明年日均pv达到60。
3.明年把驾照考出来,话说,这个驾照都考了三年了。
4.房子装修完毕,明年在新房过年。
5.买车?算了,放一放,哪里有钱,我只是一个平凡的码农。

2015年的年度总结比2014年的来的稍晚了一些,晚了10天。

发表在 生活笔记 | Comments Off on 2015年年度总结

RocketMQ学习(九):顺序消息

rocketmq的顺序消息需要满足2点:

1.Producer端保证发送消息有序,且发送到同一个队列。
2.consumer端保证消费同一个队列。

先看个例子,代码版本跟前面的一样。
Producer类:

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import com.alibaba.rocketmq.client.exception.MQBrokerException;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.MessageQueueSelector;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.common.message.MessageQueue;
import com.alibaba.rocketmq.remoting.exception.RemotingException;


/**
 * Producer,发送顺序消息
 */
public class Producer {
    public static void main(String[] args) throws IOException {
        try {
            DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");

            producer.setNamesrvAddr("192.168.0.104:9876");

            producer.start();

            String[] tags = new String[] { "TagA", "TagC", "TagD" };

            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String dateStr = sdf.format(date);
            for (int i = 0; i < 10; i++) {
                // 加个时间后缀
                String body = dateStr + " Hello RocketMQ " + i;
                Message msg = new Message("TopicTestjjj", tags[i % tags.length], "KEY" + i, body.getBytes());

                SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
                    @Override
                    public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
                        Integer id = (Integer) arg;
                        return mqs.get(id);
                    }
                }, 0);//0是队列的下标

                System.out.println(sendResult + ", body:" + body);
            }

            producer.shutdown();
        } catch (MQClientException e) {
            e.printStackTrace();
        } catch (RemotingException e) {
            e.printStackTrace();
        } catch (MQBrokerException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.in.read();
    }
}

继续阅读

发表在 编程语言 | 标签为 , | Comments Off on RocketMQ学习(九):顺序消息