首页 开发编程 正文

php中怎么得到日历

1、php中怎么得到日历,php获取日期中的年份?如果是获取当前日期的年份,可以用date('Y');如果是获取字符串当中的年份,就用字符串截取。2、php程序员面试题都有哪些?想了解IT界的那些事儿,请关注萌新程序猿!!!刚好我之前在自己...

php中怎么得到日历,php获取日期中的年份?

如果是获取当前日期的年份,可以用date('Y');如果是获取字符串当中的年份,就用字符串截取。

php程序员面试题都有哪些?

想了解IT界的那些事儿,请关注萌新程序猿!!!

刚好我之前在自己的个人网站(www.onezero.cc

)中整理过此类的知识,因此特地奉上。

首先一下,既然是php程序员,下面的知识是最基本的:

你需要了解PHP的各类基础知识,php语法、面向对象、设计模式等等,其次你需要懂得PHP的开发框架的知识,tp、laveral、yii等,再次你需要了解前端的知识,了解数据库(mysql等)的知识,了解php运行的服务器环境nginx、apache等,更进一步你需要了解redis、缓存之类,最后你需要掌握web开发安全的相关知识,比如sql注入、xss等。写接口,很多公司是前后端完全分离。个人面试整理

1.PHP的魔术变量都有什么?

__LINE__ 文件中的当前行号。 __FILE__ 文件的完整路径和文件名。如果用在被包含文件中,则返回被包含的文件名。 __DIR__ 文件所在的目录。如果用在被包括文件中,则返回被包括的文件所在的目录。 __FUNCTION__ 常量返回该函数被定义时的名字 __CLASS__ 常量返回该类被定义时的名字(区分大小写)。 __METHOD__ 类的方法名(PHP 5.0.0 新加)。返回该方法被定义时的名字(区分大小写)。 __NAMESPACE__ 当前命名空间的名称(区分大小写)。此常量是在编译时定义。

2.PHP超级全局变量(9个)

$GLOBALS 储存全局作用域中的变量 $_SERVER 获取服务器相关信息 $_REQUEST 获取POST和GET请求的参数 $_POST 获取表单的POST请求参数 $_GET 获取表单的GET请求参数 $_FILES 获取上传文件的的变量 $_ENV 获取服务器端环境变量的数组 $_COOKIE 浏览器cookie的操作 设置cookie:setcookie(name, value, expire, path, domain); 获取cookie:$_COOKIE[“user”]; 删除cookie:setcookie(“user”, “”, time()-3600);//设置过期时间 $_SESSION 服务端session的操作 使用session前一定要session_start()启动session 储存session:$_SESSION[“name”]=”King”;//数组操作 销毁session:unset($_SESSION[“name”]);//销毁一个 session_destroy()和unset($_SESSION);//销毁所有的session

3.PHP魔术函数(13个)

__construct() 实例化对象时被调用,当__construct和以类名为函数名的函数同时存在时,__construct将被调用,另一个不被调用。 __destruct() 当删除一个对象或对象操作终止时被调用。 __call() 对象调用某个方法,若方法存在,则直接调用;若不存在,则会去调用__call函数。 __get() 读取一个对象的属性时,若属性存在,则直接返回属性值;若不存在,则会调用__get函数。 __set() 设置一个对象的属性时,若属性存在,则直接赋值;若不存在,则会调用__set函数。 __toString() 打印一个对象的时被调用。如echo $obj;或print $obj; __clone() 克隆对象时被调用。如:$t=new Test();$t1=clone $t; __sleep() serialize之前被调用。若对象比较大,想删减一点东东再序列化,可考虑一下此函数。 __wakeup() unserialize时被调用,做些对象的初始化工作。 __isset() 检测一个对象的属性是否存在时被调用。如:isset($c->name)。 __unset() unset一个对象的属性时被调用。如:unset($c->name)。 __set_state() 调用var_export时,被调用。用__set_state的返回值做为var_export的返回值。 __autoload() 实例化一个对象时,如果对应的类不存在,则该方法被调用。

4.前端后端的常用开发框架都有哪些?

前端:(1) CSS: Bootstrap、EasyUI

(2)JavaScript:VUE.js、angular.Js、jQuery.js。

后端:thinkPHP、Yii、Laravel、swoole、workerman(当时只想到这几个)、。

5.如何查看防火墙开放的端口号service iptables status

6.查看防火墙特定的端口号,例如80端口的状态?netstat -an | grep 80 查看80端口被什么占用netstat -tunlp | grep 80lsof -i:80

7.Linux系统中System进程占用大量CPU,可能的原因?(1) 进入了一个死循环无法跳出来;(2) 也许是一直在等待一个信号,如从dbus上读取一个用户需要的信息; #dbus是一个为应用程序间通信的消息总线系统, 用于进程之间的通信。(3) 有可能是程序在对一个非常大的内容进行分析和处理;(4) 有可能是程序要处理的问题比较多,所以在一个个慢慢的执行。

8.说一下HTTP2.0与HTTP1.0的根本区别。

9.InnoDB和MyISAM的区别是什么,二者分别应用与什么方面?

10.用尽量多的方法说明如何提高一个网页的访问速度。

11.请设计一个通信协议,实现与摄像头之间的通信,要注意协议的安全性和可扩展性。

12.如果一个公司有几十个系统,每一个系统都需要登录,现在请你设计一个系统,可以实现每一个系统的单点登录。

其他整理

1、用PHP打印出前一天的时间格式是2017-9-5 15:30:21

echo date(‘Y-m-d H:i:s’, strtotime(‘-1 day’));

2、echo(),print(),print_r()的区别

echo是PHP语句, print和print_r是函数,语句没有返回值,函数可以有返回值(即便没有用)

print只能打印出简单类型变量的值(如int,string)

print_r可以打印出复杂类型变量的值(如数组,对象)

echo — 输出一个或者多个字符串

3、能够使HTML和PHP分离开使用的模板

smarty,Heyes Template Class等

5、使用哪些工具进行版本控制?

VS Server on Apache作服务端,WinCVS作客户端;Subversion on Apache/DAV 做服务端,TortoiseSVN做客户端,或者Subclipse做客户端.

6、如何实现字符串翻转?

strrev()

7、优化MYSQL数据库的方法。

(1).选取最适用的字段属性,应该尽量把字段设置为NOT NULL,这样在将来执行查询的时候,数据库不用去比较NULL值。

(2).使用连接(JOIN)来代替子查询(Sub-Queries)

(3).使用联合(UNION)来代替手动创建的临时表

(4).尽量少使用 LIKE 关键字和通配符

(5).使用事务和外键

8、PHP的意思

Hypertext Preprocessor

9、MYSQL取得当前时间的函数是?,格式化日期的函数是

now(), DATE_FORMAT(date,format)

10、实现中文字串截取无乱码的方法。

mb_substr()

11、您是否用过版本控制软件? 如果有您用的版本控制软件的名字是?

TortoiseSVN-1.2.6 svn-1.2.3

12、您是否用过模板引擎? 如果有您用的模板引擎的名字是?

smarty

13、请简单阐述您最得意的开发之作

14、对于大流量的网站,您采用什么样的方法来解决访问量问题?

首先,确认服务器硬件是否足够支持当前的流量

其次,优化数据库访问。

第三,禁止外部的盗链。

第四,控制大文件的下载。

第五,使用不同主机分流主要流量

第六,使用流量分析统计软件。

—————————————————————–

15、用PHP写出显示客户端IP与服务器IP的代码

16、语句include和require的区别是什么?为避免多次包含同一文件,可用(?)语句代替它们?

require()和include()除了怎样处理失败之外在各

方面都完全一样。include()产生一个警告而require()则导致一个致命错误。

换句话说,如果你想在丢失文件时停止处理页面,用require()。include() 就不是这样,脚本会继续运行。

require()无论如何都会包含文件,而include()可以有选择地包含.

代替用

include_once

require_once

17、如何修改SESSION的生存时间.

18、有一个网页地址, 比如PHP开发资源网主页: ,如何得到它的内容?

19、在HTTP 1.0中,状态码401的含义是(?);如果返回“找不到文件”的提示,则可用 header 函数,其语句为(?);

未授权(Unauthorized)

有哪些好用却不为人知的国产软件?

这几款国产软件太可惜了!全是大厂出品,超好用,还免费,可惜知道的人太少了!各个堪称“神器”

01 滴答音乐

一款免费的音乐下载软件,可以下载一切高品质音乐!软件体积只有3M,却功能强大发,是个人用户开发的软件,全免费!

有了滴答音乐,帮你搞定所有音乐下载问题。你只需记住自己想要下载的歌曲名,在滴答音乐中进行搜索,选择后点击下载即可。

十分方便,最重要的是支持多种品质下载。

滴答音乐几乎可以下载所有的音乐,资源十分丰富,且页面无广告,使用简单!简直神奇啊!

不过,可惜的是,这个软件在一些平台上,你可能无法下载,不过不用担心,我给你下载好了安装包。

关注@旁门左道PPT ,点击我的头像,进入主页,点击私信,回复关键词【国产】,即可获取全文所有软件安装包。

02 夸克浏览器

一款阿里旗下的超实用,无广告的免费小众手机浏览器。

搜索结果中不会有竞价广告,大多数网站里的广告,都会被过滤。智能拼页的浏览方式,堪称是神器!

打开和加载的速度都特别快。我把夸克,谷歌,百度放在一起,做了一个对比,简直秒杀:

在同一手机同一网络环境下,打开浏览器的时间依次是:夸克<1秒,谷歌2秒,百度9秒(6秒打开+3秒广告)

我比较喜欢它的高速百度网盘下载功能,在浏览器下载设置里直接把下载线程调为64,你就会发现下载速度竟然高达1-5M/S,与几十K/S的龟速比起来,效率是不是高多了:

不说了,谁用谁爱~不过可惜的是,这款良心的小软件,用的人有点少……

03 爱奇艺万能播放器

爱奇艺旗下的一款免费本地视频软件,可以播放图片,视频等多种格式文件,支持几乎所有主流视频格式查看,堪称强大!

当然,也因为小众,被很多人忽视,但真的超好用!而且大厂出品,比较稳定!

这款万能播放器,提及特别小,仅有15M,启动速度快,卡顿现象几乎没有,可播放文件的格式十分丰富:支持mp4、mkv、3gp、rmvb等任意视频及音乐播放:

这个播放的格式,可以说真的无敌了!

它的功能还有很多,最让我惊喜的是,借助它可以几乎实现全速百度网盘内容的下载!只需轻松点击界面上百度云图标,登录账号,便可以实现下载,几乎全速:

用了就舍不得放下的视频播放软件!

目前这个软件已经下架了,不过我给你准备好了安装包。

关注@旁门左道PPT,点击我的头像,进入主页,点击私信,回复关键词【国产】即可获取~

04 用药助手

这是一款帮你了解医药信息的APP。

这款APP是由丁香医生团队开发,一款专门面向医生、用户等提供医药信息查询的专业查询工具,避免药物食用错误!

软件内包含40000种药品的说明书,帮助你更好地了解生活常用药品的功能;包括5000多个专业的医生给出的用药指南,防止用药错误。

也收录了近万种常见疾病的介绍以及相关治疗信息;

还有比较贴心的药物相互作用指南,这个功能真的很贴心,可以很大程度上帮助我们告别药物用错导致的副作用!

不过呢,这个软件只能作为辅助,用药还是要遵医嘱哦~

05 袋鼠输入

百度旗下的一个小众免费APP,一款用手机遥控电脑的神器工具

在电脑和手机端同时下载之后,只要在同一网络下,你就可以使用手机操控电脑,非常方便。

你可以利用它完成文字输入:

直接对着手机讲话就可以自动输入到电脑上~

你还可以把它当作一个电脑的遥控器:

汇报的时候,可以用它遥控PPT播放;

追剧的时候,可以用它遥控视频播放。

最赞的是,你还可以使用【鼠标模式】,可以直接把手机当作无线鼠标使用:

体验非常好,简直是给电脑加了一块触控板。让你再也不用担心忘了带PPT遥控器!

06 妙读

阿里旗下出品的一款读书软件,它除了界面简约清晰之外,最大的优点就是让你能充分利用碎片时间,提炼书中内容干货,让你15分钟内以最快速度、便捷的方式读透一本书。

不愧是阿里出品的图书,在妙读精选页面,每一本书推荐都很精致:

在书架板块,有超多的精选书籍,另外,所有的图书都支持听书模式,让你随时随地看书!听书模式的声音还挺自然的:

大厂的东西,还是很优秀的,知识知道的人太少了

07 给未来写封信

这是一个非常小众的国产软件,很温情,专属于你自己!给未来的你写封信!

界面做得很精致,有意境。

我个人比较喜欢写信的功能,你可以给未来的自己写一封信,并定义好时间:

想象一下,日后的某一天,你收到了来自自己的信,现在的你,看着当年或哭或笑,或吵或闹的自己,别有一番感触。

软件中,你还能看到不同人的信件,遇见与你相似的一颗灵魂。试着用这款软件去记录你现在的每一刻,邮寄给未来的自己吧!

08 折扇

腾讯收购的一款中国风的折扇知识普及软件。

界面太美了,作为一名设计师,我实在是忍不住沉浸其中。

设计美到巅峰是什么样子,大概就是折扇这款软件的样子,每一个页面都能让人欣赏半天。

这是一款科普扇子文化的软件,你可以详细地端详每款扇子。了解关于扇子的知识,除此之外,APP的动画和触感,简直让人心动,太美了!这款软件,你一定要试试!

你可以亲手体验制作扇子的过程,设计出属于自己的扇子!掌握关于扇子的文化!

另外,大家不要忘记领取这些软件的安装包!

关注@旁门左道PPT,点击我的头像,进入主页,点击私信,回复关键词【国产】即可获取~

看到这里,别忘了给我点个赞哦!

Java开发分库分表需要解决的问题及mycat是怎样实现分库分表的?

MySQL的使用场景中,读写分离只是方案中的一部分,想要扩展,势必会用到分库分表,可喜的是Mycat里已经做到了,今天花时间测试了一下,感觉还不错。

关于分库分表

当然自己也理了一下,分库分表的这些内容,如果分成几个策略或者阶段,大概有下面的几种。

最上面的第一种是直接拆表,比如数据库db1下面有test1,test2,test3三个表,通过中间件看到的还是表test,里面的数据做了这样的拆分,能够在一定程度上分解压力,如果细细品来,和分区表的套路有些像。

接下来的几类也是不断完善,把表test拆解到多个库中,多个服务器中,如果做了读写分离,全套的方案这样的拆解改进还是很大的。如此来看,数据库中间件做了很多应用和数据库之间的很多事情,能够流行起来除了技术原因还是有很多其他的因素。

分库分表的测试环境模拟

如果要在一台服务器上测试分库分表,而且要求架构方案要全面,作为技术可行性的一个判定参考,是否可以实现呢。

如果模拟一主两从的架构,模拟服务分布在3台服务器上,这样的方案需要创建9个实例,每个实例上有3个db需要分别拆分。

大体的配置如下:

master1: 端口33091

(m1)slave1: 端口33092

(m1)slave2: 端口33093

master2: 端口33071

(m2)slave1: 端口33072

(m2)slave2: 端口33073

master3: 端口33061

(m3)slave1: 端口33062

(m3)slave2: 端口33063

画个图来说明一下,其中db1,db2,db3下面有若干表,需要做sharding

所以我们需要模拟的就是这个事情。

使用Mycat碰到的几个小问题解惑

使用Mycat的时候碰到了几个小问题,感觉比较有代表性,记录了一下。

问题1:

首先是使用Mycat连接到数据库之后,如果不切换到具体的数据库下,使用[数据库名].[表名]的方式会抛出下面的错误,可见整个过程中,Mycat拦截了SQL信息做了过滤,在转换的时候找不到目标路由。当然实际使用中,规范使用肯定不会有这个问题。

mysql> select * from db1.shard_auto;

ERROR 1064 (HY000): find no Route:select * from db1.shard_auto

问题2:

在配置了sharding策略之后,insert语句抛出了下面的错误,这个是对语法的一个基本的要求。

mysql> insert into shard_mod_long values(1,'aa',date);

ERROR 1064 (HY000): partition table, insert must provide ColumnList

问题3:

如果sharding策略配置有误,很可能出现表访问正常,但是DML会有问题,提示数据冲突了。至于如何配置sharding,下面会讲。

mysql> select * from shard_mod_long;

Empty set (0.00 sec)

mysql> insert into shard_mod_long(ID,name,shard_date) values(1,'aa',current_date);

ERROR 1105 (HY000): Duplicate entry '1' for key 'PRIMARY'

问题4:

如果sharding的配置有误,很可能出现多份冗余数据。

查看执行计划就一目了然,通过data_node可以看到数据指向了多个目标库。

mysql> explain insert into shard_auto(ID,name,shard_date) values(1,'aa',current_date);

+-----------+------------------------------------------------+

| DATA_NODE | SQL |

+-----------+------------------------------------------------+

| pxcNode11 | insert into shard_auto(ID,name,shard_date) values(1,'aa',current_date) |

| pxcNode21 | insert into shard_auto(ID,name,shard_date) values(1,'aa',current_date) |

| pxcNode31 | insert into shard_auto(ID,name,shard_date) values(1,'aa',current_date) |

+-----------+------------------------------------------------+

这种情况如果有一定的需求还是蛮不错的,做sharding可惜了。问题就在于下面的这个table配置。

<table name="shard_auto" primaryKey="ID" type="global" dataNode="pxcNode11,pxcNode21,pxcNode31" rule="auto-sharding-long" />

需要去掉 type="global"的属性,让它sharding。

Mycat里面的sharding策略

Mycat的分片策略很丰富,这个是超出自己的预期的,也是Mycat的一大亮点。

大体分片规则如下,另外还有一些其他分片方式这里不全部列举:

(1)分片枚举:sharding-by-intfile

(2)主键范围:auto-sharding-long

(3)一致性hash:sharding-by-murmur

(4)字符串hash解析:sharding-by-stringhash

(5)按日期(天)分片:sharding-by-date

(6)按单月小时拆分:sharding-by-hour

(7)自然月分片:sharding-by-month

在开始之前,我们要创建下面的表来模拟几个sharding的场景,表名根据需求可以改变。

create table shard_test(ID int primary key, name varchar(20),shard_date date);

主键范围分片

主键范围分片是参考了主键值,按照主键值的分布来分布数据库在不同的库中,我们先在对应的sharding节点上创建同样的表结构。

关于sharding的策略,需要修改rule.xml文件。

常用的sharding策略已经在Mycat里面实现了,如果要自行实现也可以定制。比如下面的规则,是基于主键字段ID来做sharding,分布的算法是rang-long,引用了function rang-long,这个function是在对应的一个Java类中实现的。

<tableRule name="auto-sharding-long">

<rule>

<columns>ID</columns>

<algorithm>rang-long</algorithm>

</rule>

<function name="rang-long"

class="io.mycat.route.function.AutoPartitionByLong">

<property name="mapFile">autopartition-long.txt</property>

当然主键的范围是不固定的,可以根据需求来定制,比如按照一百万为单位,或者1000位单位,文件是 autopartition-long.txt 文件的内容默认如下,模板里是分为了3个分片,如果要定制更多的就需要继续配置了,目前来看这个配置只能够承载15亿的数据量,可以根据需求继续扩展定制。

# range start-end ,data node index

# K=1000,M=10000.

0-500M=0

500M-1000M=1

1000M-1500M=2

插入一些数据来验证一下,我们可以查看执行计划来做基本的验证,配置无误,数据就根据规则流向了指定的数据库下的表里。

mysql> explain insert into shard_auto(ID,name,shard_date) values(1,'aa',current_date);

+-----------+------------------------------------------------+

| DATA_NODE | SQL |

+-----------+------------------------------------------------+

| pxcNode11 | insert into shard_auto(ID,name,shard_date) values(1,'aa',current_date) |

+-----------+------------------------------------------------+

还有一个查看sharding效果的小方法,比如我插入一个极大的值,保证和其他数据不在一个分片上,我们运行查询语句两次,结果会有点变化。

sharing的效果

mysql> select * from shard_auto;

+---------+------+------------+

| ID | name | shard_date |

+---------+------+------------+

| 1 | aa | 2017-09-06 |

| 2 | bb | 2017-09-06 |

| 5000001 | aa | 2017-09-06 |

+---------+------+------------+

3 rows in set (0.00 sec)

稍作停顿,继续运行。

mysql> select * from shard_auto;

+---------+------+------------+

| ID | name | shard_date |

+---------+------+------------+

| 5000001 | aa | 2017-09-06 |

| 1 | aa | 2017-09-06 |

| 2 | bb | 2017-09-06 |

+---------+------+------------+

3 rows in set (0.01 sec)

Hash分片

Hash分片其实企业级应用尤其广泛,我觉得一个原因是通过这种数据路由的方式,得到的数据情况是基本可控的,和业务的关联起来比较直接。很多拆分方法都是根据mod方法来平均分布数据。

sharding的策略在rule.xml里面配置,还是默认的mod-long规则,引用了算法mod-long,这里是根据sharding的节点数来做的,默认是3个。

<tableRule name="mod-long">

<rule>

<columns>id</columns>

<algorithm>mod-long</algorithm>

</rule>

</tableRule>

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">

<!-how many data nodes -->

<property name="count">3</property>

</function>

比如查看两次insert的结果情况。

mysql> explain insert into shard_mod_long(ID,name,shard_date) values(4,'dd',current_date);

+-----------+------------------------------------------------+

| DATA_NODE | SQL |

+-----------+------------------------------------------------+

| pxcNode22 | insert into shard_mod_long(ID,name,shard_date) values(4,'dd',current_date) |

+-----------+------------------------------------------------+

mysql> explain insert into shard_mod_long(ID,name,shard_date) values(5,'ee',current_date);

+-----------+------------------------------------------------+

| DATA_NODE | SQL |

+-----------+------------------------------------------------+

| pxcNode23 | insert into shard_mod_long(ID,name,shard_date) values(5,'ee',current_date) |

+-----------+------------------------------------------------+

可以看到数据还是遵循了节点的规律,平均分布。

至于schema.xml的配置,是整个分库的核心,我索性也给出一个配置来,供参考。

<?xml version="1.0"?>

<!DOCTYPE mycat:schema SYSTEM "schema.dtd">

<mycat:schema xmlns:mycat="http://io.mycat/">

<!-定义MyCat的逻辑库 -->

<schema name="db1" checkSQLschema="false" sqlMaxLimit="100" >

<table name="shard_mod_long" primaryKey="ID" type="global" dataNode="pxcNode11,pxcNode21,pxcNode31" rule="mod-long" />

<table name="shard_auto" primaryKey="ID" type="global" dataNode="pxcNode11,pxcNode21,pxcNode31" rule="auto-sharding-long" />

</schema>

<!-定义MyCat的数据节点 -->

<dataNode name="pxcNode11" dataHost="dtHost" database="db1" />

<dataNode name="pxcNode21" dataHost="dtHost2" database="db1" />

<dataNode name="pxcNode31" dataHost="dtHost3" database="db1" />

<!-定义数据主机dtHost,连接到MySQL读写分离集群 ,schema中的每一个dataHost中的host属性值必须唯一-->

<!-dataHost实际上配置就是后台的数据库集群,一个datahost代表一个数据库集群 -->

<!-balance="1",全部的readHost与stand by writeHost参与select语句的负载均衡-->

<!-writeType="0",所有写操作发送到配置的第一个writeHost,这里就是我们的hostmaster,第一个挂了切到还生存的第二个writeHost-->

<dataHost name="dtHost" maxCon="500" minCon="20" balance="1"

writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">

<!--心跳检测 -->

<heartbeat>show slave status</heartbeat>

<!--配置后台数据库的IP地址和端口号,还有账号密码 -->

<writeHost host="hostMaster" url="192.168.163.128:33091" user="mycat_user" password="mycat" />

</dataHost>

<dataHost name="dtHost2" maxCon="500" minCon="20" balance="1"

writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">

<!--心跳检测 -->

<heartbeat>show slave status</heartbeat>

<!--配置后台数据库的IP地址和端口号,还有账号密码 -->

<writeHost host="hostMaster" url="192.168.163.128:33071" user="mycat_user" password="mycat" />

</dataHost>

<dataHost name="dtHost3" maxCon="500" minCon="20" balance="1"

writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">

<!--心跳检测 -->

<heartbeat>show slave status</heartbeat>

<!--配置后台数据库的IP地址和端口号,还有账号密码 -->

<writeHost host="hostMaster" url="192.168.163.128:33061" user="mycat_user" password="mycat" />

</dataHost>

</mycat:schema>

=================================================================================================

用Mycat,学会数据库读写分离、分表分库

php疑难杂症铺 2017-09-13 14:31

用Mycat,学会数据库读写分离、分表分库

系统开发中,数据库是非常重要的一个点。除了程序的本身的优化,如:SQL语句优化、代码优化,数据库的处理本身优化也是非常重要的。主从、热备、分表分库等都是系统发展迟早会遇到的技术问题问题。Mycat是一个广受好评的数据库中间件,已经在很多产品上进行使用了。希望通过这篇文章的介绍,能学会Mycat的使用。

安装

Mycat官网:http://www.mycat.io/

可以了解下Mycat的背景和应用情况,这样使用起来比较有信心。

Mycat下载地址:http://dl.mycat.io/

官网有个文档,属于详细的介绍,初次入门,看起来比较花时间。

下载:

建议大家选择 1.6-RELEASE 版本,毕竟是比较稳定的版本。

安装:

根据不同的系统选择不同的版本。包括linux、windows、mac,作者考虑还是非常周全的,当然,也有源码版的。(ps:源码版的下载后,只要配置正确,就可以正常运行调试,这个赞一下。)

Mycat的安装其实只要解压下载的目录就可以了,非常简单。

安装完成后,目录如下:

目录说明binmycat命令,启动、重启、停止等catletcatlet为Mycat的一个扩展功能confMycat 配置信息,重点关注libMycat引用的jar包,Mycat是java开发的logs日志文件,包括Mycat启动的日志和运行的日志。

配置

Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:

文件说明server.xmlMycat的配置文件,设置账号、参数等schema.xmlMycat对应的物理数据库和数据库表的配置rule.xmlMycat分片(分库分表)规则

Mycat的架构其实很好理解,Mycat是代理,Mycat后面就是物理数据库。和Web服务器的Nginx类似。对于使用者来说,访问的都是Mycat,不会接触到后端的数据库。

我们现在做一个主从、读写分离,简单分表的示例。结构如下图:

服务器IP说明Mycat192.168.0.2mycat服务器,连接数据库时,连接此服务器database1192.168.0.3物理数据库1,真正存储数据的数据库database2192.168.0.4物理数据库2,真正存储数据的数据库

Mycat作为主数据库中间件,肯定是与代码弱关联的,所以代码是不用修改的,使用Mycat后,连接数据库是不变的,默认端口是8066。连接方式和普通数据库一样,如:jdbc:mysql://192.168.0.2:8066/

server.xml

示例

重点关注下面这段,其他默认即可。

参数说明user用户配置节点--name登录的用户名,也就是连接Mycat的用户名--password登录的密码,也就是连接Mycat的密码--schemas数据库名,这里会和schema.xml中的配置关联,多个用逗号分开,例如需要这个用户需要管理两个数据库db1,db2,则配置db1,dbs--privileges配置用户针对表的增删改查的权限,具体见文档吧

我这里配置了一个账号test 密码也是test,针对数据库lunch,读写权限都有,没有针对表做任何特殊的权限。

schema.xml

schema.xml是最主要的配置项,首先看我的配置文件。

参数说明schema数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应dataNode分片信息,也就是分库相关配置dataHost物理数据库,真正存储数据的数据库

每个节点的属性逐一说明:

schema:

属性说明name逻辑数据库名,与server.xml中的schema对应checkSQLschema数据库前缀相关设置,建议看文档,这里暂时设为folsesqlMaxLimitselect 时默认的limit,避免查询全表

table:

属性说明name表名,物理数据库中表名dataNode表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的nameprimaryKey主键字段名,自动生成主键时需要设置autoIncrement是否自增rule分片规则名,具体规则下文rule详细介绍

dataNode

属性说明name节点名,与table中dataNode对应datahost物理数据库名,与datahost中name对应database物理数据库中数据库名

dataHost

属性说明name物理数据库名,与dataNode中dataHost对应balance均衡负载的方式writeType写入方式dbType数据库类型heartbeat心跳检测语句,注意语句结尾的分号要加。

应用场景

数据库分表分库

配置如下:

我在192.168.0.2、192.168.0.3均有数据库lunch。

lunchmenu、restaurant、userlunch、users这些表都只写入节点dn1,也就是192.168.0.2这个服务,而dictionary写入了dn1、dn2两个节点,也就是192.168.0.2、192.168.0.3这两台服务器。分片的规则为:mod-long。

主要关注rule属性,rule属性的内容来源于rule.xml这个文件,Mycat支持10种分表分库的规则,基本能满足你所需要的要求,这个必须赞一个,其他数据库中间件好像都没有这么多。

table中的rule属性对应的就是rule.xml文件中tableRule的name,具体有哪些分表和分库的实现,建议还是看下文档。我这里选择的mod-long就是将数据平均拆分。因为我后端是两台物理库,所以rule.xml中mod-long对应的function count为2,见下面部分代码:

数据库读写分离

配置如下:

这样的配置与前一个示例配置改动如下:

删除了table分配的规则,以及datanode只有一个

datahost也只有一台,但是writehost总添加了readhost,balance改为1,表示读写分离。

以上配置达到的效果就是102.168.0.2为主库,192.168.0.3为从库。

注意:Mycat主从分离只是在读的时候做了处理,写入数据的时候,只会写入到writehost,需要通过mycat的主从复制将数据复制到readhost,这个问题当时候我纠结了好久,数据写入writehost后,readhost一直没有数据,以为是自己配置的问题,后面才发现Mycat就没有实现主从复制的功能,毕竟数据库本身自带的这个功能才是最高效稳定的。

至于其他的场景,如同时主从和分表分库也是支持的了,只要了解这个实现以后再去修改配置,都是可以实现的。而热备及故障专业官方推荐使用haproxy配合一起使用,大家可以试试。

使用

Mycat的启动也很简单,启动命令在Bin目录:

如果在启动时发现异常,在logs目录中查看日志。

wrapper.log 为程序启动的日志,启动时的问题看这个

mycat.log 为脚本执行时的日志,SQL脚本执行报错后的具体错误内容,查看这个文件。mycat.log是最新的错误日志,历史日志会根据时间生成目录保存。

mycat启动后,执行命令不成功,可能实际上配置有错误,导致后面的命令没有很好的执行。

Mycat带来的最大好处就是使用是完全不用修改原有代码的,在mycat通过命令启动后,你只需要将数据库连接切换到Mycat的地址就可以了。如下面就可以进行连接了:

连接成功后可以执行sql脚本了。

所以,可以直接通过sql管理工具(如:navicat、datagrip)连接,执行脚本。我一直用datagrip来进行日常简单的管理,这个很方便。

Mycat还有一个管理的连接,端口号是9906.

连接后可以根据管理命令查看Mycat的运行情况,当然,喜欢UI管理方式的人,可以安装一个Mycat-Web来进行管理,有兴趣自行搜索。

简而言之,开发中使用Mycat和直接使用Mysql机会没有差别。

常见问题

使用Mycat后总会遇到一些坑,我将自己遇到的一些问题在这里列一下,希望能与大家有共鸣:

Mycat是不是配置以后,就能完全解决分表分库和读写分离问题?

Mycat配合数据库本身的复制功能,可以解决读写分离的问题,但是针对分表分库的问题,不是完美的解决。或者说,至今为止,业界没有完美的解决方案。

分表分库写入能完美解决,但是,不能完美解决主要是联表查询的问题,Mycat支持两个表联表的查询,多余两个表的查询不支持。 其实,很多数据库中间件关于分表分库后查询的问题,都是需要自己实现的,而且节本都不支持联表查询,Mycat已经算做地非常先进了。

分表分库的后联表查询问题,大家通过合理数据库设计来避免。

Mycat支持哪些数据库,其他平台如 .net、PHP能用吗?

官方说了,支持的数据库包括MySQL、SQL Server、Oracle、DB2、PostgreSQL 等主流数据库,很赞。

尽量用Mysql,我试过SQL Server,会有些小问题,因为部分语法有点差异。

Mycat 非JAVA平台如 .net、PHP能用吗?

可以用。这一点MyCat做的也很棒。

怎样查苹果手机什么时候到期?

先在 iPhone 主界面找到“设置”图标按钮,点击它进入“设置”界面。在设置里找到“通用”并点击它打开。在“通用”里找到“关于本机”,点击它打开。在“关于本机”界面里我们可以看到 iphone 的一些相关信息,在这里我们只需要的是序列号,把它记下,一会儿用到。官网查激活时间首先打开浏览器,在浏览器的地址栏里输入

https://selfsolve.apple.com/agreementWarrantyDynamic.do

在打开的“查看您的保修服务和支持期限”页面里的“输入您的硬件序列号”下的输入框里输入第一步里我们找到的 iphone 手机序列号,输入好了之后点击右边的“继续”来进行查询。当查询结果出来之后,就会跳到新的界面,在新的界面里可以看到 iphone 的相关保修服务信息,如果信息是有效的,这里的图标就全部是绿色的。在这个页面的第三项是 iphone 手机硬件的保修截止日期,也许有人会问了,我们要找的是激活时间,怎么没有呀,我说呀,别急,下面笔者给大家慢慢道来,其它了没有什么多说的,呵呵,在这里我们看到的是保修的截止日期,其它在这个日期的基础上倒回去一年,就是我们手上 iphone 的激活日期了。呵呵,简单吧,就这么简单。三、通过其它第三方网站进行查询激活时间第三方网站查询的很多,下面笔者推荐威锋网的查询工具。查询地址:

http://act.weiphone.com/wetools/index.php

在地址栏输入以上地址来打开威锋网的查询工具。在打开的查询工具的输入框里输入我们从 iphone 里的序列号,然后点击右边的放大镜,呵呵,现在是放大镜,以后就不一定了咯,反正就是要进行搜索的意思。等待一段时间的查询之后,就会查询出我们手上 iphone 的相关信息了。一样的,我们在这里只能看到的是保修日期,并没有看到激活时间,一样的道理,在原有的保修截止日期里倒回去一年就是我们 iphone 的激活时间了。简单吧,还有,这里可是中文的咯,很容易就能看清楚吧。

本文转载自互联网,如有侵权,联系删除