Hadoop集群搭建及运行初步

一直以来对Hadoop都非常有兴趣,所以这一段时间研究可以下Hadoop集群的搭建,今天写一篇小文章,主要是当做自己的笔记,因为写Hadoop怎么搭建的太多了,好了废话不多说,下面开始正文 一、环境准备 系统环境 因为我个人比较喜欢Linux,另外很多资料都是基于Linux的,所以本文也不能例外,系统当然是Linux啦,开发是老夫最喜欢的Ubuntu,当然这个是看自己喜欢那个版本 安装JDK 运行Hadoop需要jre环境,所以如果你的机器没有装JDK,那么就装吧,Ubuntu可以用apt-get install安装,也可以到这个地方:http://www.oracle.com/technetwork/java/javase/downloads/index.html下载然后安装,我个人比较喜欢后一种,因为这么我们可以自己选择装到哪个地方,有利于我们自己配JAVA_HOME、CLASSPATH以及PATH,配置如下: vim /etc/profile 然后在里面添加: export JAVA_HOME=/home/jdk1.7.0_40 export CLASSPATH=".:$JAVA_HOME/lib:$CLASSPATH" export PATH="$JAVA_HOME/:$JAVA_HOME/bin:$PATH" 然后执行生效 source /etc/profile 我们可以任何目录下面测试JDK安装是否成功 实现SSH无密码登陆 因为hadoop namenode要悄悄的SSH到各datanode中去启动相应的JVM进程,所以必须实现namenode能无密码登陆到datanode所在机器 配置命令如下: sudo apt-get install ssh ssh-keygen -t rsa -P " -f ~/.ssh/id_rsa cat /home/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys 可以用命令: ssh localhost 检查是否配置成功,如果有提示授权成功等字样,则表示配置成功。 二、安装Hadoop 环境准备好之后,就要开始安装Hadoop,Hadoop有很多版本,我们是以hadoop-1.2.1为基础,首先下载Hadoop,下载地址:http://www.apache.org/dyn/closer.cgi/hadoop/common/,下载之后我们把它copy到/home下,解压: tar -zxvf hadoop-1.2.1-bin.tar.gz 解压之后我们找到Hadoop的conf文件夹,下面我们的配置都将在这个文件夹下 首先要配置的文件是:hadoop-env.sh,我们打开这个文件,找到配置JVAV_HOME的那一行,把注释打开,写上我们安装的JDK的路径 配置core-site.xml,打开该文件,在文件中添加: <configuration> <property> <name>hadoop.tmp.dir</name> <value>/hadoop</value> </property> <property> <name>dfs.name.dir</name> <value>/hadoop/name</value> </property> <property> <name>fs.default.name</name> <value>hdfs://localhost:9000</value> </property> </configuration> 配置hdfs-site.xml,同样添加: <configuration> <property> <name>dfs.data.dir</name> <value>/hadoop/data</value> </property> </configuration> 配置mapred-site.xml,也是添加 <configuration> <property> <name>mapred.job.tracker</name> <value>localhost:9001</value> </property> </configuration> 下面我们同样需要配置hadoop_home,同样是打开 vim /etc/profile 在里面添加: ...

June 28, 2015 · 1 分钟 · Bridge Li

MySQL优化初步

这一段时间看了学长推荐的一本书:《高性能MySQL》,感觉还不错,今天写一篇读书笔记,供自己和需要的人参考。 一、数据库优化简介 数据库优化的目的 ①. 避免出现页面访问错误,主要是数据库连接timeout产生页面5XX错误、由于慢查询造成页面无法加载和由于阻塞造成数据无法提交; ②. 增加数据库的稳定性,很多数据库问题都是由于低效的查询引起的; ③. 优化用户体验,流畅页面的访问速度、良好的网站功能体验 从哪几个方面对数据库优化 所谓一图胜千言,所以我们先看一下,下面这张图: 从这张图上,我们可以清晰的看到,我们优化的重点和代价,另外这几个方面我们分别可以做些什么呢? ①.在SQL及索引层面,首先是我们要写出一些结构良好的SQL和建立有效的索引 ②.数据库表结构,我们应该根据数据库的一些范式,减少冗余,建立一个利于查询的库表结构 ③.系统配置,例如TCP/IP的连接数、文件的打开数等等 ④. 硬件,包括内存、CPU等,IO设备等等 二、SQL语句优化 在SQL优化之前,我们首先肯定是要查询到哪些SQL需要优化,所以下面让我们先打开MySQL的慢查询日志 MySQL慢查日志的开启方式和存储格式 我们先看几个命令: show variables like 'slow_query_log'; set global slow_query_log=on; set global slow_query_log_file='/home/mysql/sql_log/mysql-slow.log'; set global log_queries_not_using_indexes=on; set global long_query_time=1; 这几条命令相信不用说,大家都能看得懂,需要说明的是最后一条的时间单位是“秒”,本例中意思是说大于“1秒”的都认为是慢查询,当然实际情况下“1秒”很多时候也是太长了,记录下来这些信息之后我们就可以分析和查看这些日志了,分析和查看MySQL的慢查询日志有两个常见的工具,分别是mysqldumpslow和pt-query-digest,第一个是MySQL官方提供的,第二个是一个商业软件,至于他们怎么用,这里就不多说了,找到这些用问题的SQL之后,我们就可以对这些SQL进行优化了,一般有问题的SQL主要是一下这些: ①. 查询次数多且每次查询占用时间长的SQL,通常是pt-query-digest分析的前几个查询; ②. IO大的SQL,注意pt-query-digest分析中的Rows examine项 ③. 未命中索引的SQL,注意pt-query-digest分析中Rows examine和Rows Send的对比 通过explain查询和分析SQL的执行计划 explain返回各列的含义 table: 显示这一行数据是关于那张表的 type: 这是重要的列,显示连接使用了何种类型。从最好到最差的连接类型为const、eq_reg、ref、range、index和All possible_keys 显示可能应用在这张表中的索引。如果为空,没有可能的索引。 key: 实际使用的索引 key_len: 使用索引的长度,在不损失精确性的情况下,长度越短越好 ref: 显示索引的哪一列被使用了,如果可能的话,是一个常数 rows: MySQL认为必须检查的用来返回请求数据的行数 extra: 看到Using filesort和Using temporary的时候,查询就需要优化了,Using temporary需要MySQL常见一个临时表来存储结果,这通常发生在不同的列集进行ORDER BY上,而不是GROUP BY上 count()和max()的优化 max函数通常是查询最后一个数据,我们可以对max函数包含的列添加一个索引; count函数是用来计数的,我们只需要了解count()和count(id)的差别就好了,count()返回的是有多少行,count(id)返回的是id不为null的有多少行,所以这是有差别的 ...

June 14, 2015 · 1 分钟 · Bridge Li

Java中常见的日期处理方法

在实际工作中日期是我们非常用的一种类型,其原因相信不用我说了大家都明白,今天就写一篇文章记录一下自己在工作中常用的日期处理 日期格式化 日期格式化,在工作中,很多时候我们拿到的日期的格式不是我们想要的,那么就需要我们把它格式化成我们想要的,那么怎么做呢? 举个例子:我们想格式化当日时间为:2015-05-31 22:05:30,就可以这么做: package cn.bridgeli.demo.date; import java.text.SimpleDateFormat; import java.util.Date; public class DateTest { public void testSimpleDateFormat() { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = new Date(); String now = simpleDateFormat.format(date); System.out.println(now); } } 那么大家就可以根据自己的需要,去格式化大家想要的格式了,需要注意的一点是:我这里的“HH”是大写的表明是24时计时法,如果写成小写的“hh”,就变成12时计时法了。 获取当前的月份 我想有些人可能已经想到了,把上面的改成 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM"); 这个是能达到目的,但不够优雅,也不是官方所推荐的,也比较难以维护,下面我们看看标准的实现 package cn.bridgeli.demo.date; import java.util.Calendar; import java.util.Date; public class DateTest { public void testSimpleDateFormat() { Calendar calendar = Calendar.getInstance(); System.out.println(calendar.get(Calendar.MONTH)); } } 其实在JDK的早期版本中,Date类型是直接有genMonth()方法的,但由于Date类型比较简单,功能有限,所以后来JDK就把这个方法给废弃了(但为了兼容,目前还是可以用的),然后创造了Calendar,所以我们可以利用Calendar获取年份、月份、日期等等,具体可以查询JDK的API 获得当前周几 这个其实和上一个很类似,具体不多说了,大家查JDK的API中的Calendar就可以看到了 package cn.bridgeli.demo.date; import java.util.Calendar; import java.util.Date; public class DateTest { public static void main(String[] args) { Date today = new Date(); Calendar c = Calendar.getInstance(); c.setTime(today); int weekday = c.get(Calendar.DAY_OF_WEEK); System.out.println(weekday); } } 当前日期加一天 有时候我们,不仅需要当前时间,而且需要当前时间往前推或者往后推,这个时候我们就可以这么做: ...

May 31, 2015 · 2 分钟 · Bridge Li

持续集成(C I)工具Jenkins入门

这几天研究了一下持续集成(CI)工具Jenkins,感觉很强大,入门也很简单,今天就写一个入门的小例子,对于一般性的小项目足够用了,如果大家用到了更复杂的相信学会这篇文章之后,也一定能自己搞定了 安装 Jenkins是Java开发的,我们只需要到他的官网:http://jenkins-ci.org下载一个war包,扔到servlet容器(例如:tomcat)中,启动就可以了,和普通的war启动没什么差别,如果你还不会,那么你需要补J2EE的基础了。 安装插件 启动完成之后,是这样的, Jenkins自己已经帮我们安装了好多很好用的插件,但有些还是要我们自己装,例如:Git Client Plugin、Git Plugin,要安装这些,我们只需要点击左边的“系统管理” –> 管理插件 –> 可选插件,找到这两个插件装上就好了,装好插件下一步就是配置了 配置 配置,同样“系统管理” –> 系统设置,下面开始配置: ①. Maven Configuration配置 就是maven的settings文件的位置 ②. JDK配置 新增JDK,然后大家一看就应该懂了,尽量不要自动安装 ③. Git 也一样,就是Git的路径,需要注意的是:Git的路径一直要到bin下面的exe文件(Linux还没用过,所以不清楚,但我相信大家都懂得了) ④. Maven配置 这个和JDK的配置是一样的 ⑤. Maven项目配置 Maven仓库的地址,我选的是第三个Local to the workspace,其实无所谓 ⑥. Jenkins URL 就改成127.0.0.1吧,或者其他合适的,邮件地址就写自己的啦 ⑦. Git plugin 这个相信不用多说了,Git我们都配过 这些目前是必须的配置,其他的大家就根据需要或者自己的理解,要么不配也行 需要说明的是,我没有配ant,用到了可以自己配一下,一样的,配置完成后选择“保存”就好了 新建一个任务 这个大家都能找到在哪,然后进入到 填入Item名称,选择构建一个maven项目,点击“OK”到下一页,需要说明的: ①. 源码管理,这个也是最重要的,我选的是Git,这也是在一开始我安装那两个插件的原因,如果不安装那两个插件,是不会有Git这个选项的,然后键入要构建的项目的URL,点击“Add”,添加用户名和密码,切记一定要这么选择 其中Username是默认的,可以改,但Kind和Private Key强烈建议和我选的一样,否则可能会报代码拉不下来的错误,反正我是被这个错浪费了一天,然后这么选之后就对了,所以建议大家这么干,当然也可以自己选择其他的,大家可以试试。 ②. 构建触发器 Poll SCM、Build periodically这个是我们配置定时任务,也就是定时自动构建项目的,他们的区别: Poll SCM:定时检查源码变更(根据SCM软件的版本号),如果有更新就checkout最新code下来,然后执行构建动作。我的配置如下: * 5 * * * * (每5分钟检查一次源码变化) Build periodically:周期进行项目构建(它不care源码是否发生变化),我的配置如下: 0 2 * * * (每天2:00 必须build一次源码) ③. 其他的配置 这些配置只有源码管理是必须的,其他的大家就可以根据需要自己进行配置了,如:Pre Steps和Post Steps,就是构建之前和构建之后做一些什么工作,例如构建之前我们需要删除一些文件,构建之后我们需要把构建后的文件copy到tomcat中,他们也支持shell编程的,其实很简单易懂,读者看一眼自己亲手操作一下就知道了,陆游说过,纸上得来终觉浅,绝知此事要躬行 ...

May 24, 2015 · 1 分钟 · Bridge Li

Nginx配置使用入门

Nginx作为当今数一数二的负载均衡服务器,应用十分广泛,今天记录一下,大名鼎鼎的Nginx的配置信息 一个简单的负载均衡的示例,把www.domain.com均衡到本机不同的端口,也可以改为均衡到不同的地址上。 http { upstream myproject { server 127.0.0.1:8000 weight=3; server 127.0.0.1:8001; server 127.0.0.1:8002; server 127.0.0.1:8003; } server { listen 80; server_name www.domain.com; location / { proxy_pass http://myproject; } } } weight就是权重,数值越大,分配到这个服务器的概率就越大,以本例来说,分配8000上的概率为二分之一,其他的三个均为为六分之一,另外需要注意的是:proxy_pass和upstream一定要一样 注:这么配置仅仅是解决了负载均衡的问题,但是没有解决session共享的问题,为了解决session共享我们有两个方案: 配置粘连,也就是说,只要某一个请求被分配到该服务器,那么今后的该客端的所有请求全都分配到该服务器上; 在代码中解决session共享问题 目前针对这两种方案,我都不是很熟悉,我将来会写一篇文章来解决这个问题 静态资源处理 location ~ .(jpg|png|jpeg|bmp|gif|swf|css|js)$ { expires 30d; root /nginx-1.8.0;#root break; } 就是说上面的这些静态资源文件都是相对于:/nginx-1.8.0的,所以如果我们代码中写的路径是img/bridgeli.png,那么我们就需要在nginx-1.8.0建一个img目录,把我们bridgeli.png放在里面。 完整示例 #!nginx # 使用的用户和组 user www www; # 指定工作衍生进程数 worker_processes 2; # 指定 pid 存放的路径 pid /var/run/nginx.pid; # [ debug | info | notice | warn | error | crit ] # 可以在下方直接使用 [ debug | info | notice | warn | error | crit ] 参数 error_log /var/log/nginx.error_log info; events { # 允许的连接数 connections 2000; # use [ kqueue | rtsig | epoll | /dev/poll | select | poll ] ; # 具体内容查看 http://wiki.codemongers.com/事件模型 use kqueue; } http { include conf/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] ' "$request" $status $bytes_sent ' "$http_referer" "$http_user_agent" ' "$gzip_ratio"'; log_format download '$remote_addr - $remote_user [$time_local] ' "$request" $status $bytes_sent ' "$http_referer" "$http_user_agent" ' "$http_range" "$sent_http_content_range"'; client_header_timeout 3m; client_body_timeout 3m; send_timeout 3m; client_header_buffer_size 1k; large_client_header_buffers 4 4k; gzip on; gzip_min_length 1100; gzip_buffers 4 8k; gzip_types text/plain; output_buffers 1 32k; postpone_output 1460; sendfile on; tcp_nopush on; tcp_nodelay on; send_lowat 12000; keepalive_timeout 75 20; #lingering_time 30; #lingering_timeout 10; #reset_timedout_connection on; server { listen one.example.com; server_name one.example.com www.one.example.com; access_log /var/log/nginx.access_log main; location / { proxy_pass http://127.0.0.1/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; client_max_body_size 10m; client_body_buffer_size 128k; client_body_temp_path /var/nginx/client_body_temp; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_read_timeout 90; proxy_send_lowat 12000; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; proxy_temp_path /var/nginx/proxy_temp; charset UTF-8; } error_page 404 /404.html; location /404.html { root /spool/www; charset on; source_charset UTF-8; } location /old_stuff/ { rewrite ^/old_stuff/(.*)$ /new_stuff/$1 permanent; } location /download/ { valid_referers none blocked server_names *.example.com; if ($invalid_referer) { #rewrite ^/ http://www.example.com/; return 403; } #rewrite_log on; rewrite /download/*/mp3/*.any_ext to /download/*/mp3/*.mp3 rewrite ^/(download/.*)/mp3/(.*)..*$ /$1/mp3/$2.mp3 break; root /spool/www; autoindex on; access_log /var/log/nginx-download.access_log download; } location ~* ^.+.(jpg|jpeg|gif)$ { root /spool/www; access_log off; expires 30d; } } 这是Nginx官方网站的一个例子,说实话里面的很多配置我也不是很清楚,但很多并不是非常难以理解 ...

May 17, 2015 · 3 分钟 · Bridge Li

ANT(build)脚本模板示例

近来虽然Maven构建的项目越来越盛行,但是依然还有很多遗留(暂且称之为遗留吧)项目依然是由ANT编译的,今天老夫就整理一下自己目前公司项目用到的ANT模板,既作为老夫的学习笔记,以供将来查看,也分享出来供需要的参考,因为比较简单易懂,就不多说了,直接上代码 <?xml version="1.0" encoding="UTF-8"?> <!-- Ant工程build模板 ant build file Example: ant -Dprofile=dev deploy test IDC测试环境 dev 本地开发环境 (default) --> <project name="antProject" basedir="." default="prompt"> <property name="javac.version" value="1.6" /> <property name="project.name" value="projectname" /> <property name="source.encoding" value="UTF-8" /> <property name="deploy.dir" value="/tmp/${project.name}" /> <!-- project var set --> <property name="target.path" value="build" /> <property name="target.root.path" value="${target.path}/ROOT" /> <property name="target.root.classes" value="${target.root.path}/WEB-INF/classes" /> <property name="webroot.path" value="WebRoot" /> <property name="compileSrc" value="src" /> <property name="compileDest" value="${target.root.classes}" /> <property name="env.dir" value="env" /> <property name="env.cfg" value="${env.dir}/${profile}" /> <tstamp> <format property="now" pattern="yyyyMMddHHmmss" /> </tstamp> <path id="compileClassPath"> <fileset dir="${webroot.path}/WEB-INF/lib"> <include name="*.jar" /> </fileset> </path> <target name="prompt" description="show prompt information"> <echo>Please choose task: clean, compile, war, deploy. ${line.separator} Example: ${line.separator} ant compile ${line.separator} ant -Dprofile=test deploy </echo> </target> <target name="clean"> <delete dir="${target.path}" /> <mkdir dir="${target.path}" /> <delete dir="${compileDest}" /> <mkdir dir="${compileDest}" /> <delete dir="${target.root.classes}" /> <mkdir dir="${target.root.classes}" /> <echo>cleaned for ${compileDest}, ${target.root.path},${target.path}/*.war</echo> </target> <target name="compile" depends="clean,testIfProfileSet"> <echo>starting compile the source from ${compileSrc}</echo> <javac srcdir="${compileSrc}" includeantruntime="false" fork="true" memoryinitialsize="256m" memorymaximumsize="512m" destdir="${compileDest}" classpathref="compileClassPath" encoding="${source.encoding}" source="${javac.version}" target="${javac.version}" debug="true" verbose="false" optimize="true" deprecation="false"> </javac> <copy todir="${compileDest}"> <fileset dir="${compileSrc}" excludes="**/*.svn,**/*.java" /> </copy> <echo>compiled classes copied to ${compileDest}</echo> <copy todir="${target.root.path}"> <fileset dir="${webroot.path}" excludes="**/*.svn,**/*.java" /> </copy> <echo>copied to ${webroot.path} to ${compileDest}</echo> <echo>compile finished</echo> </target> <target name="testIfProfileSet"> <echo>ant param profile: ${profile}</echo> <condition property="isProfileSet"> <!-- <isset property="${profile}" /> --> <isset property="${profile}" /> --> <or> <equals arg1="${profile}" arg2="dev" /> <equals arg1="${profile}" arg2="test" /> </or> </condition> <antcall target="profileProvided"> </antcall> <antcall target="noProfile"> </antcall> </target> <target name="profileProvided" if="isProfileSet"> <copy todir="${target.root.classes}"> <fileset dir="${env.cfg}" /> </copy> <echo>copied config files ${env.cfg} to ${target.root.classes}</echo> </target> <target name="noProfile" if="isProfileSet"> <echo>ant param profile is none, use default config files</echo> </target> <target name="war" depends="compile"> <jar jarfile="${target.path}/${project.name}-${profile}${now}.war"> <fileset dir="${target.root.path}"> <include name="**/*" /> <exclude name="**/*.fla" /> <exclude name="**/*.mp3" /> <exclude name="**/*.as" /> <exclude name="**/*.bak" /> <exclude name="**/*.swd" /> <exclude name="**/*.db" /> </fileset> </jar> </target> <target name="deploy" depends="compile"> <delete dir="${deploy.dir}" /> <mkdir dir="${deploy.dir}" /> <copy todir="${deploy.dir}"> <fileset dir="${target.root.path}"> </fileset> </copy> <echo>deploy ${target.root.path} to ${deploy.dir}</echo> </target> </project>

May 10, 2015 · 2 分钟 · Bridge Li

Spring加Mybatis实现MySQL数据库主从读写分离

上周在一个同事的指点下,实现了Spring加Mybatis实现了MySQL的主从读写分离,今天记一下笔记,以供自己今后参考,下面是配置文件的写法。 数据源也就是jdbc.properties,因为是主从读写分离,那么肯定有两个数据源了 jdbc.driver=org.mariadb.jdbc.Driver # 从库,只读 slave.jdbc.url=jdbc:mariadb://xxx.xxx.xxx.xxx:3306/xxx?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&noAccessToProcedureBodies=true&autoReconnect=true slave.jdbc.username=xxx slave.jdbc.password=xxx # 主库,需要写 master.jdbc.url=jdbc:mariadb://xxx.xxx.xxx.xxx:3306/xxx?characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&noAccessToProcedureBodies=true&autoReconnect=true master.jdbc.username=xxx master.jdbc.password=xxx 这个非常简单和普通的区别不是很大,另外数据库的驱动是:mariadb,动下面就是第二个配置文件spring.xml spring.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd "> <!-- Import properties file --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- Auto Scan --> <context:component-scan base-package="cn.bridgeli.demo" /> </beans> 这个文件很简单,有两个作用,①. 引入数据源配置文件;②. spring扫描的文件的路径 spring-mybatis.xml配置文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <bean id="slaveDataSourceImpl" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${slave.jdbc.url}" /> <property name="username" value="${slave.jdbc.username}" /> <property name="password" value="${slave.jdbc.password}" /> <!-- 检查数据库连接池中空闲连接的间隔时间,单位是分,默认值:240,如果要取消则设置为0 --> <property name="idleConnectionTestPeriodInMinutes" value="10" /> <!-- 连接池中未使用的链接最大存活时间,单位是分,默认值:60,如果要永远存活设置为0 --> <property name="idleMaxAgeInMinutes" value="10" /> <!-- 每个分区最大的连接数 --> <property name="maxConnectionsPerPartition" value="20" /> <!-- 每个分区最小的连接数 --> <property name="minConnectionsPerPartition" value="10" /> <!-- 分区数 ,默认值2,最小1,推荐3-4,视应用而定 --> <property name="partitionCount" value="3" /> <!-- 每次去拿数据库连接的时候一次性要拿几个,默认值:2 --> <property name="acquireIncrement" value="3" /> <!-- 缓存prepared statements的大小,默认值:0 --> <property name="statementsCacheSize" value="50" /> <!-- 在做keep-alive的时候的SQL语句 --> <property name="connectionTestStatement" value="select 1 from dual" /> <!-- 在每次到数据库取连接的时候执行的SQL语句,只执行一次 --> <property name="initSQL" value="select 1 from dual" /> <property name="closeConnectionWatch" value="false" /> <property name="logStatementsEnabled" value="true" /> <property name="transactionRecoveryEnabled" value="true" /> </bean> <bean id="masterDataSourceImpl" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"> <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${master.jdbc.url}" /> <property name="username" value="${master.jdbc.username}" /> <property name="password" value="${master.jdbc.password}" /> <!-- 检查数据库连接池中空闲连接的间隔时间,单位是分,默认值:240,如果要取消则设置为0 --> <property name="idleConnectionTestPeriodInMinutes" value="10" /> <!-- 连接池中未使用的链接最大存活时间,单位是分,默认值:60,如果要永远存活设置为0 --> <property name="idleMaxAgeInMinutes" value="10" /> <!-- 每个分区最大的连接数 --> <property name="maxConnectionsPerPartition" value="20" /> <!-- 每个分区最小的连接数 --> <property name="minConnectionsPerPartition" value="10" /> <!-- 分区数 ,默认值2,最小1,推荐3-4,视应用而定 --> <property name="partitionCount" value="3" /> <!-- 每次去拿数据库连接的时候一次性要拿几个,默认值:2 --> <property name="acquireIncrement" value="3" /> <!-- 缓存prepared statements的大小,默认值:0 --> <property name="statementsCacheSize" value="50" /> <!-- 在做keep-alive的时候的SQL语句 --> <property name="connectionTestStatement" value="select 1 from dual" /> <!-- 在每次到数据库取连接的时候执行的SQL语句,只执行一次 --> <property name="initSQL" value="select 1 from dual" /> <property name="closeConnectionWatch" value="false" /> <property name="logStatementsEnabled" value="true" /> <property name="transactionRecoveryEnabled" value="true" /> </bean> <!-- DataSource/Master --> <bean id="masterDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"> <property name="targetDataSource" ref="masterDataSourceImpl" /> </bean> <bean id="masterTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="masterDataSource" /> </bean> <bean id="masterTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="masterTransactionManager" /> </bean> <!-- DataSource/Slave --> <bean id="slaveDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"> <property name="targetDataSource" ref="slaveDataSourceImpl" /> </bean> <bean id="slaveTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="slaveDataSource" /> </bean> <bean id="slaveTransactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"> <property name="transactionManager" ref="slaveTransactionManager" /> </bean> <!-- Mybatis/Master --> <bean id="masterSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="masterDataSource"></property> <property name="configLocation" value="classpath:mybatis.xml" /> <property name="typeAliasesPackage" value="cn.bridgeli.demo.entity" /> <property name="mapperLocations"> <list> <value>classpath:cn/bridgeli/demo/mapper/master/*.xml</value> </list> </property> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.bridgeli.demo.mapper.master" /> <property name="sqlSessionFactoryBeanName" value="masterSqlSessionFactory" /> </bean> <!-- Mybatis/Slave --> <bean id="slaveSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="slaveDataSource"></property> <property name="configLocation" value="classpath:mybatis.xml" /> <property name="typeAliasesPackage" value="cn.bridgeli.demo.entity" /> <property name="mapperLocations"> <list> <value>classpath:cn/bridgeli/demo/mapper/slave/*.xml</value> </list> </property> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.bridgeli.demo.mapper.slave" /> <property name="sqlSessionFactoryBeanName" value="slaveSqlSessionFactory" /> </bean> <!-- Configuration transaction advice --> <tx:advice id="txAdvice" transaction-manager="masterTransactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="update*" propagation="REQUIRED" /> <tx:method name="delete*" propagation="REQUIRED" /> <tx:method name="get*" read-only="true" propagation="SUPPORTS" /> <tx:method name="list*" read-only="true" propagation="SUPPORTS" /> </tx:attributes> </tx:advice> <!-- Configuration transaction aspect --> <aop:config> <aop:pointcut id="systemServicePointcut" expression="execution(* cn.bridgeli.demo.service.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="systemServicePointcut" /> </aop:config> </beans> 这个配置文件老夫是完整的copy了下来,看起来也比较易懂,就不做解释了,需要说明的mybatis下那些dao的接口,分别对应cn.bridgeli.demo.mapper.master、cn.bridgeli.demo.mapper.slave,cn.bridgeli.demo.mapper.master下的这些dao接口是要写的,另一个是读的,这些接口对应的配置文件肯定就是他们对应的文件夹下面的xml文件了,在将来的项目中几乎可以照抄 ...

May 3, 2015 · 3 分钟 · Bridge Li

MyBatis下最好的分页实现:mybatis-paginator使用入门

前两天写一个项目,发现在MyBatis下一个最好的分页实现类库mybatis-paginator,今天就写一篇其入门教程供大家参考。 先引入maven依赖 <dependency> <groupId>com.github.miemiedev</groupId> <artifactId>mybatis-paginator</artifactId> <version>1.2.15</version> </dependency> 从这个依赖中,我们可以看到 1 他是mybatis的一个插件,2 其开源在GitHub上,感兴趣的可以去GitHub上搜源码看看,既然是mybatis的插件,下一步肯定就是和mybatis的集成了. 和mybatis集成 ①. 新建一个mybatis.xml的配置文件,其内容如下: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <setting name="cacheEnabled" value="true" /> <setting name="lazyLoadingEnabled" value="true" /> </settings> <plugins> <plugin interceptor="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor"> <property name="dialectClass" value="com.github.miemiedev.mybatis.paginator.dialect.MySQLDialect" /> <property name="asyncTotalCount" value="true" /> </plugin> </plugins> </configuration> ②. 和spring集成,即在spring-mybatis.xml中引入该文件 ...... <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:mybatis.xml" /> <property name="typeAliasesPackage" value="cn.bridgeli.demo.entity" /> <property name="mapperLocations" value="classpath:cn/bridgeli/demo/mapper/*.xml" /> </bean> ...... 因为这个文件太长,就不贴全文了,仅把位置这一块贴出来,当我们把这些配置工作做好之后,下一步就是如何使用了。 ...

April 26, 2015 · 2 分钟 · Bridge Li

Shell编程入门

一、Shell入门 我们先看一个小例子,永恒的经典:Hello World #!/bin/sh var="Hello World!" echo $var 保存,文件名为:hello 我们发现文件的第一行虽是一个注释,但是说明了文件的执行是由/bin/sh来执行,所以我们这么来执行这个文件: /bin/sh hello 就可以看到结果了,但我们知道在Linux下,一个文件是否可以执行是由文件属性来决定的,那么我们是否可以给他加上可执行权限,来执行这个文件呢? 先执行如下命令: chmod u+x hello 然后我们在直接敲命令:hello,看到什么现象? 所以一个文件被执行有这两个途径 二、Shell语法入门 输入/输出内部命令 ①. echo 输出命令 ②. read 输入命令 例如: #!/bin/sh echo Name: read NAME echo Phone: read PHONE echo SNAME,SPHONE > contact.txt if条件语句 在看if条件语句之前,我们先看一下:测试命令执行结果,在Linux下正确的命令执行结果为0,否则为其他值,我们可以用: echo $? 来看上一个命令的执行结果,懂了这些之后,我们在看那些常见语法 if 条件测试命令串 then 条件为真时执行的命令 else 条件为假时执行的命令 fi 注:if和then必须是两行,如果放一行,请在then前加“;” 例如: #!/bin/sh echo "Input file name:" read NAME if [ -d "$NAME" ]; then echo "Dir" else echo "Not Dir" fi case条件语句 case 条件测试命令串 in 表达式1) 分支1执行的命令 ;; 表达式2) 分支2执行的命令 ;; *) 其他命令 ;; esac 例如: ...

April 19, 2015 · 2 分钟 · Bridge Li

Maven项目如何生成测试报告

刚工作的时候,当时公司对代码质量要求比较高,每一个人的代码都要写junit,而且要生成测试报告,项目经理要看行覆盖率和分支覆盖率,记得当时的项目是用ant编译的,生成测试报告那个复杂啊,不会写,现在用了maven,发现这在maven下根本不是事,只需要在pom.xml中配置一个插件即可,废话不多说,直接上代码: <build> <finalName>Demo</finalName> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>cobertura-maven-plugin</artifactId> <version>2.5.2</version> <configuration> <encoding>UTF-8</encoding> <formats> <format>html</format> <format>xml</format> </formats> </configuration> </plugin> </plugins> </build> 然后打开cmd切到pom.xml所在文件夹,运行命令: mvn cobertura:cobertura 即可,然后我们打开{project}targetsitecoberuraindex.html就可以看到测试报告了,这个测试报告里面不仅有行覆盖率还有分支覆盖率,例如: 相信不用我解释,看这篇文章的人一定能看懂是什么意思。 下面是一些cobertura插件的常用命令 mvn cobertura:help 查看cobertura插件的帮助 mvn cobertura:clean 清空cobertura插件运行结果 mvn cobertura:check 运行cobertura的检查任务 mvn cobertura:cobertura 运行cobertura的检查任务并生成报表,报表生成在target/site/cobertura目录下 cobertura:dump-datafile Cobertura Datafile Dump Mojo mvn cobertura:instrument Instrument the compiled classes 至于有什么效果,请大家自己写一个例子,跑一下就可以了。 最后多说一点,关于maven的插件其实非常多,用法也相对都比较简单,网上的资料也比较多,今天这篇文章算是抛砖引玉,所以推荐大家今后尽量用maven编译项目

April 12, 2015 · 1 分钟 · Bridge Li