分类目录归档:JavaEE

linux下如何实现mysql数据库每天定时自动备份

需要将数据库进行每天定时自动备份,所以网上找了各种方式就行了测试,遇到很多坑,特此记录下来,步骤是东拼西凑的,虽然也是网上找的,但都是经过亲自测试,一定能用,针对部署时期遇到的问题和解决方式都记录了下来。

1、创建备份目录:
为了方便,在/home保存备份文件;

cd
mkdir /home/dbback
cd /home/dbback
2、创建备份Shell脚本:
注意把以下命令中的DatabaseName换为实际的数据库名称;
当然,你也可以使用其实的命名规则!

vi bkDatabaseName.sh
输入/粘贴以下内容:

#!/bin/bash
mysqldump -uusername -ppassword DatabaseName > /home/dbback/DatabaseName_$(date +%Y%m%d_%H%M%S).sql
对备份进行压缩:

#!/bin/bash
mysqldump -uusername -ppassword DatabaseName | gzip > /home/dbback/DatabaseName_$(date +%Y%m%d_%H%M%S).sql.gz
注意:
把 username 替换为实际的用户名;
把 password 替换为实际的密码;
把 DatabaseName 替换为实际的数据库名;

3、添加可执行权限:
chmod u+x bkDatabaseName.sh
添加可执行权限之后先执行一下,看看脚本有没有错误,能不能正常使用;

./bkDatabaseName.sh
注:这里可能会报错
Warning: Using a password on the command line interface can be insecure.
导出MySQL数据库的时候采用mysqldump命令,出现”Warning: Using a password on the command line interface can be insecure.”的错误提示,当然数据库肯定也没有能备份下来。这个问题应该是在MySQL5.6+版本的时候就有出现,可能是为了确保数据库的安全性采用的保护机制。

解决方法、修改数据库配置文件

1、我们需要修改数据库配置文件,这个要看我们数据库的配置的,有些是在/etc/my.cnf,有些是/etc/my.conf

我们需要在[client]部分添加脚本:

host=localhost
user=数据库用户
password=’数据库密码’

这里参数要修改成我们自己的。

2、采用命令导出和导入数据库

其实在这个时候,我们如果采用”详解使用mysqldump命令备份还原MySQL数据用法整理”介绍的方法也是可以使用的,虽然依旧有错误提示,但是数据库还是可以导出的。您肯定和老左一样是追求细节的人,一点点问题都不能有,但我们可以用下面的命令导出和导入,就没有错误提示。

#导出数据库

mysqldump –defaults-extra-file=/etc/my.cnf database > database.sql

#导入数据库

mysql –defaults-extra-file=/etc/my.cnf database < database.sql

这里我们可以看到上面的命令和以前常用的快速导入和导入命令有所不同了,需要加载我们配置的MYSQL配置文件,这个红色部分要根据我们实际的路径修改。用这样的命令导出备份和导入是没有错误提示的。

4、添加计划任务
检测或安装 crontab
确认crontab是否安装:
执行 crontab 命令如果报 command not found,就表明没有安装

# crontab
-bash: crontab: command not found
如时没有安装 crontab,需要先安装它,具体步骤请参考:
CentOS下使用yum命令安装计划任务程序crontab
使用rpm命令从CentOS系统盘安装计划任务程序crontab

添加计划任务
执行命令:

crontab -e
这时就像使用vi编辑器一样,可以对计划任务进行编辑。
输入以下内容并保存:

*/1 * * * * /home/backup/bkDatabaseName.sh
具体是什么意思呢?

意思是每一分钟执行一次shell脚本“/home/backup/bkDatabaseName.sh”。

1、额外学习,crontab用法
crontab命令用于安装、删除或者列出用于驱动cron后台进程的表格。用户把需要执行的命令序列放到crontab文件中以获得执行。
每个用户都可以有自己的crontab文件。/var/spool/cron下的crontab文件不可以直接创建或者直接修改。该crontab文件是通过crontab命令创建的

在crontab文件中如何输入需要执行的命令和时间。该文件中每行都包括六个域,其中前五个域是指定命令被执行的时间,最后一个域是要被执行的命令。
每个域之间使用空格或者制表符分隔。格式如下:
minute hour day-of-month month-of-year day-of-week commands
合法值 00-59 00-23 01-31 01-12 0-6 (0 is sunday)
除了数字还有几个个特殊的符号就是”*”、”/”和”-“、”,”,*代表所有的取值范围内的数字,”/”代表每的意思,”/5″表示每5个单位,”-“代表从某个数字到某个数字,”,”分开几个离散的数字。

-l 在标准输出上显示当前的crontab。
-r 删除当前的crontab文件。
-e 使用VISUAL或者EDITOR环境变量所指的编辑器编辑当前的crontab文件。当结束编辑离开时,编辑后的文件将自动安装。

 

2、例子:
每天早上6点
0 6 * * * echo “Good morning.” >> /tmp/test.txt //注意单纯echo,从屏幕上看不到任何输出,因为cron把任何输出都email到root的信箱了。

每两个小时
0 */2 * * * echo “Have a break now.” >> /tmp/test.txt

晚上11点到早上8点之间每两个小时和早上八点
0 23-7/2,8 * * * echo “Have a good dream” >> /tmp/test.txt

每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点
0 11 4 * 1-3 command line

1月1日早上4点
0 4 1 1 * command line SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个帐号 HOME=/

每小时执行/etc/cron.hourly内的脚本
01 * * * * root run-parts /etc/cron.hourly
每天执行/etc/cron.daily内的脚本
02 4 * * * root run-parts /etc/cron.daily

每星期执行/etc/cron.weekly内的脚本
22 4 * * 0 root run-parts /etc/cron.weekly

每月去执行/etc/cron.monthly内的脚本
42 4 1 * * root run-parts /etc/cron.monthly

注意: “run-parts”这个参数了,如果去掉这个参数的话,后面就可以写要运行的某个脚本名,而不是文件夹名。

每天的下午4点、5点、6点的5 min、15 min、25 min、35 min、45 min、55 min时执行命令。
5,15,25,35,45,55 16,17,18 * * * command

每周一,三,五的下午3:00系统进入维护状态,重新启动系统。
00 15 * * 1,3,5 shutdown -r +5

每小时的10分,40分执行用户目录下的innd/bbslin这个指令:
10,40 * * * * innd/bbslink

每小时的1分执行用户目录下的bin/account这个指令:
1 * * * * bin/account

每天早晨三点二十分执行用户目录下如下所示的两个指令(每个指令以;分隔):
20 3 * * * (/bin/rm -f expire.ls logins.bad;bin/expire$#@62;expire.1st)

每年的一月和四月,4号到9号的3点12分和3点55分执行/bin/rm -f expire.1st这个指令,并把结果添加在mm.txt这个文件之后(mm.txt文件位于用户自己的目录位置)。
12,55 3 4-9 1,4 * /bin/rm -f expire.1st$#@62;$#@62;mm.txt

5、测试任务是否执行
很简单,我们就执行几次“ls”命令,看看一分钟过后文件有没有被创建就可以了!

如果任务执行失败了,可以通过以下命令查看任务日志:

# tail -f /var/log/cron
输出类似如下

Maven WEB 项目使用ProGuard进行混淆,最佳解决方案

近期公司的Android项目做了混淆,虽说对于保护代码并不是100%的,但混淆后的代码可以使那些不法份子难以阅读,这样也能对代码的保护做出贡献。
于是,公司写的一大堆WEB项目也想做保护。但几大问题随之而来:

公司的所有项目全部是Maven项目,网上的混淆方案不是陈旧就是无效
网上的大部分解决方案感觉像是对简单DEMO进行混淆,根本不能用于复杂的WEB项目中
网上的大部分解决方案是针对Android项目的,针对WEB的少之又少
针对以上问题,本人花费一个月研究了WEB+Maven项目的混淆,终于收获果实,解决了这一大空缺难题。

项目介绍
就如之前所述,我们要混淆的项目绝不是一个简单的WEB DEMO,必须要包含了大量第三方框架。
本文中介绍的项目使用了主流的一些框架:

Spring 4.1.1.RELEASE
SpringMVC 4.1.1.RELEASE
JackSon 2.5.0
MyBatis 3.3.0
Shiro 1.2.3
Log4J 1.2.17
SLF4J 1.7.10
Druid Pool 1.0.15
patchca 1.0.0
Jetty 9.2.7.v20150116
项目包结构

该项目是典型的Maven WEB项目,对于Maven WEB项目的结构不再赘述,这里对各种包做一下解释:

annotation 注解包,里面是自己写的注解类,主要混淆对象
controller SpringMVC的控制器包,主要混淆对象
credntials Shiro的自定义凭证,次要混淆对象
dao DAO包,主要混淆对象
exception 异常包,自定义了一些异常,主要混淆对象
filter Shiro的自定义过滤器,次要混淆对象
interceptor Shiro的自定义拦截器,次要混淆对象
job SpringTASK的定时任务包,次要混淆对象
mapper Mybatis的XML映射文件包,非混淆对象
model 实体包,非混淆对象
realm Shiro的自定义域包,次要混淆对象
service 实体的服务包,次要混淆对象
token Shiro的自定义令牌包,次要混淆对象
utils 公司自己的工具类,主要混淆对象
主要混淆对象 对类的名称、属性、方法名都进行混淆
次要混淆对象 对类的名称不混淆,类的属性、方法名选择性混淆
非混淆对象 不进行混淆,混淆后可能出现异常

Maven 配置(pom.xml)
本文的重头戏,使用Maven集成的ProGuard插件,混淆配置不用单独建立文件

<?xml version=”1.0″ encoding=”UTF-8″?>
<project xmlns=”http://maven.apache.org/POM/4.0.0″
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd”>
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<groupId>…</groupId>
<artifactId>zhukun.shiro-spring</artifactId>
<version>1.0-SNAPSHOT</version>

<!– 属性–>
<properties>
<!– 项目编码–>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!– 单元测试包–>
<junit.version>4.12</junit.version>
<!– JAVAEE支持包–>
<jstl.version>1.2</jstl.version>
<servlet.version>3.1.0</servlet.version>
<!– 日志包–>
<log4j.version>1.2.17</log4j.version>
<slf4j.version>1.7.10</slf4j.version>
<aspectj.version>1.6.12</aspectj.version>
<!– commons支持–>
<commons-logging.version>1.1.3</commons-logging.version>
<commons-collections.version>3.2.1</commons-collections.version>
<commons-fileupload.version>1.3.1</commons-fileupload.version>
<!– shiro安全框架–>
<shiro.version>1.2.3</shiro.version>
<!– druid连接池–>
<druid.version>1.0.15</druid.version>
<!– 数据库及数据库框架–>
<mysql.version>5.1.30</mysql.version>
<mybatis.version>3.3.0</mybatis.version>
<mybatis-spring.version>1.2.3</mybatis-spring.version>
<!– Mybatis分页插件–>
<mybatis-paginator.version>1.2.16</mybatis-paginator.version>
<!– Mybatis生成器插件–>
<mybatis-generator.version>1.3.2</mybatis-generator.version>
<!– Spring及SpringMVC支持包–>
<spring.version>4.1.1.RELEASE</spring.version>
<jackson.version>2.5.0</jackson.version>
<!– 验证码支持包–>
<patchca.version>1.0.0</patchca.version>
<!– Jetty插件–>
<jetty.version>9.2.7.v20150116</jetty.version>
<!– Maven编译插件–>
<maven-compiler.version>2.3.2</maven-compiler.version>
</properties>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>${commons-logging.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-quartz</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons-collections.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${servlet.version}</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>${commons-fileupload.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>${mybatis-paginator.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.patchca</groupId>
<artifactId>patchca</artifactId>
<version>${patchca.version}</version>
</dependency>
</dependencies>

<build>
<finalName>shiro-spring</finalName>
<!–使Maven打包时能打包src目录下的XML文件–>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler.version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
<webApp>
<contextPath>/shiro-spring</contextPath>
</webApp>
<httpConnector>
<!– 设置端口–>
<port>8080</port>
</httpConnector>
</configuration>
</plugin>

<!– MyBatis自动生成Mapper插件–>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>${mybatis-generator.version}</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>

<!– ProGuard混淆插件–>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.11</version>
<executions>
<execution>
<!– 混淆时刻,这里是打包的时候混淆–>
<phase>package</phase>
<goals>
<!– 使用插件的什么功能,当然是混淆–>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<!– 是否将生成的PG文件安装部署–>
<attach>true</attach>
<!– 是否混淆–>
<obfuscate>true</obfuscate>
<!– 指定生成文件分类 –>
<attachArtifactClassifier>pg</attachArtifactClassifier>
<options>
<!– JDK目标版本1.7–>
<option>-target 1.7</option>
<!– 不做收缩(删除注释、未被引用代码)–>
<option>-dontshrink</option>
<!– 不做优化(变更代码实现逻辑)–>
<option>-dontoptimize</option>
<!– 不路过非公用类文件及成员–>
<option>-dontskipnonpubliclibraryclasses</option>
<option>-dontskipnonpubliclibraryclassmembers</option>
<!– 优化时允许访问并修改有修饰符的类和类的成员 –>
<option>-allowaccessmodification</option>
<!– 确定统一的混淆类的成员名称来增加混淆–>
<option>-useuniqueclassmembernames</option>
<!– 不混淆所有包名,本人测试混淆后WEB项目问题实在太多,毕竟Spring配置中有大量固定写法的包名–>
<option>-keeppackagenames</option>
<!– 不混淆所有特殊的类–>
<option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,LocalVariable*Table,*Annotation*,Synthetic,EnclosingMethod</option>
<!– 不混淆所有的set/get方法,毕竟项目中使用的部分第三方框架(例如Shiro)会用到大量的set/get映射–>
<option>-keepclassmembers public class * {void set*(***);*** get*();}</option>

<!– 不混淆job包下的所有类名,且类中的方法也不混淆–>
<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.job.** { &lt;methods&gt;; }</option>
<!– 不混淆filter包下的所有类名,这里主要是对Shiro的路踢人过滤器混淆,对类的属性和方法进行了混淆–>
<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.filter.** </option>
<!– 不混淆凭证包下的所有类名,但对类中的属性、方法进行混淆,原因是Spring配置中用到了这个类名–>
<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.credntials.** </option>
<!– 混淆目的同上,这个是拦截器的包,包中有防止重复提交的拦截器–>
<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.interceptor.** </option>
<!– 混淆目的同上,这个是域包,包中有用户登录域–>
<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.realm.** </option>
<!– 不混淆model包中的所有类以及类的属性及方法,实体包,混淆了会导致ORM框架及前端无法识别–>
<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.model.** {*;}</option>
<!– 以下两个包因为大部分是Spring管理的Bean,不对包类的类名进行混淆,但对类中的属性和方法混淆–>
<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.service.** </option>
<option>-keep class com.chinatelecom.gz.wy.zhukun.shiro_spring.dao.**</option>
</options>
<outjar>${project.build.finalName}-pg.jar</outjar>
<!– 添加依赖,这里你可以按你的需要修改,这里测试只需要一个JRE的Runtime包就行了 –>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
</libs>
<!– 加载文件的过滤器,就是你的工程目录了–>
<inFilter>com/chinatelecom/gz/wy/zhukun/shiro_spring/**</inFilter>
<!– 对什么东西进行加载,这里仅有classes成功,毕竟你也不可能对配置文件及JSP混淆吧–>
<injar>classes</injar>
<!– 输出目录–>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
</project>

以上代码中的注释足够各位参考了,若有问题欢迎留言

执行
clean package -DskipTests

使用Maven运行以上代码,执行完成后在target目录中会生成三个文件:

classes-pg.jar 混淆后的classes文件,里面包含完整的项目结构
proguard_map.txt 混淆内容的映射
proguard_seed.txt 参与混淆的类
混淆完成后,将classes-pg.jar解压到应用服务器覆盖原有的classes文件,通常目录为

X:\jetty9或tomcat7\webapps\shiro-spring\WEB-INF\classes

运行服务,项目运行正常

反编译
既然是混淆了的代码,那我们现在作为盗码者来反编译一下classes文件

可以看出,混淆成功了,盗码者读起来不是一二般的痛苦,我们的目的已经达到

遗留问题
虽然混淆是在Maven打包的时候进行,但是生成的war包及classes目录并未混淆,还需要将jar包中的内容提取,比较麻烦,不知道有没有让生成的war包就是已经混淆的办法。
本人的JAVA环境是JDK1.7 64位,其它的JDK并未尝试
不能对Spring等配置文件混淆,这样包结构还是存在,减弱了盗码者的读码难度