首页 开发编程 正文

php案例怎么使用

用于在运行时检查或修改方法、类、接口的行为。反射可用于获取有关一些的有用信息类getClass()方法用于获取对象所属的类的名称。构造函数getConstructors()方法用于获取对象所属类的公共构造函数。该示例在运行时检查简单Java对象的字段。我们将使用Java反射来发现此类所有字段的名称。我们将构造一个Person对象并将O...

php案例怎么使用,java的反射到底是有什么用处?

谢邀。在Java中,反射是一种API,用于在运行时检查或修改方法、类、接口的行为。

反射所需的类在java.lang.reflect包下提供。反射为我们提供了有关对象所属类的信息,以及可以使用该对象执行的该类的方法。通过反射,我们可以在运行时调用方法,而与它们所使用的访问说明符无关。反射可用于获取有关一些的有用信息类 getClass()方法用于获取对象所属的类的名称。构造函数 getConstructors()方法用于获取对象所属类的公共构造函数。方法 getMethods()方法用于获取对象所属类的公共方法。简单的例子

为了先清楚下反射的用处,我们将看一个非常基本的示例,该示例在运行时检查简单Java对象的字段。

让我们创建一个简单的Person类,其中仅包含name和age字段,而根本不包含任何方法。这是Person类:

现在,我们将使用Java反射来发现此类所有字段的名称。为了欣赏反射的力量,我们将构造一个Person对象并将Object作为引用类型:

这个测试告诉我们,我们能够得到的数组Field对象从我们人的对象,即使参考对象是对象的父类。

在上面的示例中,我们仅对这些字段的名称感兴趣,但是还有很多事情可以做,我们将在后续部分中看到更多示例。

注意我们如何使用一个辅助方法来提取实际的字段名,这是一个非常基本的代码:

重点观察如果知道方法的名称和参数类型,则可以通过反射调用该方法。为此,我们使用以下两种方法getDeclaredMethod():创建要调用的方法的对象。该方法的语法是Class.getDeclaredMethod(名称,参数类型)name-要创建其对象的方法的名称parametertype-参数是Class对象的数组

invoke():要在运行时调用类的方法,我们使用以下方法——

Method.invoke(对象,参数)如果类的方法不接受任何方法 参数,然后将null用作参数。通过反射,我们可以在类的类对象的帮助下访问类的私有变量和方法,并通过使用对象来调用方法,如上所述。为此,我们使用以下两种方法。

Class.getDeclaredField(FieldName):用于获取私有字段。返回指定类型字段名称的字段类型的对象。Field.setAccessible(true): 允许访问该字段,而与该字段使用的访问修饰符无关。

使用发射的优势可扩展性功能:应用程序可以通过使用其完全限定的名称创建可扩展性对象的实例来使用外部的用户定义类。调试和测试工具:调试器使用反射的属性检查类的私有成员。缺点性能开销:反射操作比非反射操作的性能要慢,因此应避免在对性能敏感的应用程序中经常调用的代码段中避免这样做。内部曝光:反射代码破坏了抽象,因此可能会随着平台升级而改变行为。

PHP删除目录下所有的文件?

引言

作为服务器端编程语言,PHP当然具备了操作系统文件的能力。今天我们来说一下使用PHP如何删除某个目录下的所有文件。

今天我们从最简单的形式讨论,但目录下的操作。

学习时间

我们说PHP是一个函数库毫不为过,因为针对各种功能,它都封装了许多内置的函数,拿来用就可以了。而文件目录操作函数,我们推荐使用glob。

该函数的参数形式:

array glob( string $pattern[, int $flags = 0] )

用于寻找与模式匹配的文件路径。使用起来代码应该是这样的:

首先使用 glob 模式匹配出目录下所有文件,这会返回一个数组。然后遍历,再使用 is_file 函数判定是否文件类型,如果是则调用 unlink 函数删除。

逻辑大概就是这样子。在Linux操作系统下,上面的模式扫描不出来隐藏文件。如果要把隐藏文件扫描出来,需要修改一下匹配模式如下:

遍历和文件类型判断逻辑相同。

极简主义

我们知道解决问题,不会是一种单一的办法,我们总是有很多方式实现同样的需求。那么对于上述的代码,对于强迫症同学来说,还是写的有些拖沓了,要是一行能搞定就好了。

真的可以一样搞定。我们借助于PHP的内置函数遍历操作函数 array_map 可以轻松实现。代码如下:

是不是少了很多手动造轮子的粗糙感。但是,这个函数缺少了 is_file 判断,是有一定风险的。特别是回调使用 unlink 这样的删除操作,尤其需要注意。

把 glob 函数的返回值使用 (array) 进行强制类型转换,是为了防止出现返回 false,不能直接传递到 array_filter 进行过滤的缘故。

面向对象

写惯了JAVA的同学应该对类库的方法操作严重依赖不能自拔,PHP也是有配套OOP方法的,只是我们用的太少,没有系统地学习罢了。下面提贴出来一个 OOP 风格的代码来解决这个问题。

不做解释,因为用的太少。为什么?因为看看 $di $ri 对象实例的操作,还有最后 rmdir unlink 的函数操作,你终究明白,要做到真正的面向对象,还差得远呢!

共同努力吧~~

写在最后

很令人伤心,本想提供一个OOP的实现,还是被迫用了函数方法,我们已经尽力了。整体而言,函数操作和函数操作,更适合PHP流程处理。

Happy coding :_)

我是 @程序员小助手 ,持续分享编程知识,欢迎关注。

为什么那么多公司不用?

随着时代的变化,技术在不断发展,编程语言的重要性也在发生变化。所以,要我们在两门语言中二选一,通常很困难。在这篇文章里,我们要讨论的是Java和.NET之间的“战争”。

.NET和Java是两个最突出的技术平台,你可以用它们来构建软件、网站和Web应用程序。由于它们在各自的领域都负有盛名,企业在构建应用程序时通常很难决定哪个更适合它们。在比较这两种技术之前,你首先要知道如何使用这两种技术中的一种来构建应用程序。我们将在这篇文章中对它们进行比较,但我们的主要目的是让企业知道哪种选择更适合它们。

Java和.NET之间的主要区别

Java和.NET的一个主要区别是,Java(通常是Java企业版)可以运行在任何一种操作系统上,而.NET只能运行在不同版本的Windows上。即使.NET有开源实现,但仍然是以Windows用户为目标。

此前,微软发布了.NET CORE 3,这是最新的.NET Framework改进版。 这个改进版本的一个优点是:.NET CORE现在既是开源的又是跨平台的。 另外,.NET CORE还提供了很多对开发、Web、云计算和移动应用程序都非常有用的新特性。

不过,.NET CORE并不支持.NET Framework的所有特性。 但不管怎样,选择.NET CORE总是会更好,原因如下: .NET CORE是一个开源的软件框架,企业和开发人员可以很容易地用它来开发应用程序。

与.NET Framework不同,.NET CORE是跨平台的,它支持三种不同的操作系统——Windows、OSX和Linux。 而说到Java,因为借助了Java虚拟机,它基本上可以运行在任何设备和操作系统上,成了一个可移植的独立于平台的编程工具。

.NET和Java的不同

还有一个区别与集成开发环境(IDE)有关。IDE就是一种软件,为开发人员提供了重要的工具,帮助他们构建和测试软件应用程序。.NET有一个默认的IDE,那就是Visual Studio,一个可以帮助开发人员构建应用程序的神奇工具。

对于Java来说,市场上有四种面向Java开发人员的主流IDE,分别是Eclipse、IntelliJ Idea、Oracle NetBeans和Oracle JDeveloper。

从上面给出的统计数据(这些数据是由著名求职网站Indeed研究得出的)可以看出,与.NET开发人员相比,市场对Java开发人员的需求更旺盛。与.NET开发工作相比,求职者更倾向于寻找Java开发工作。

然而,无论是.NET还是Java,市场对这两个职位的需求都很旺盛。它们的需求和重要性可以从企业的项目中看出来。

Java和.NET的关键特性支持的语言

Java的主要特点是它在不同的平台上使用了同一种语言,用Java开发的程序可以在不同的操作系统上运行。Java支持Python、Ruby、Groovy、Scala和Kotlin等编程语言。

.NET Framework支持用于后端开发和Web服务开发的编程语言,比如C++#和C++。目前,它支持大约20种语言。用户可以根据自己的需要使用任何一门语言进行编程,比如VB.NET、C#.NET、Perl,等等。 因此,.NET支持多语言编程环境,而Java使用了单一编程语言,但可以支持多种语言。

IDE

Java IDE由代码编辑器、编译器和调试器组成。Eclipse、IntelliJ Idea、Oracle NetBeans,除此之外,为了使代码的编写和测试更容易,还有一个专门为此而设计的Oracle JDeveloper。这些IDE提供了内置插件和自动填充选项,在这些插件和自动填充选项的帮助下,Java的灵活性得到了提升,同时也为创新提供了空间。 .NET平台有Visual Studio,开发人员可以利用宏来编辑、编译和定制API的运行时行为。

性能和兼容性

Java字节码在执行之前被转换为机器码,而.NET先编译组装好,然后在系统中运行,所以C#在运行时环境中更有优势。 Java 7之前的版本不支持简单数据结构的switch case。 .NET C#支持字符串变量和原生泛型的switch case。ASP.NET支持Linq(Language Integrated Query)在,但Java不支持。

安全性

因为缺乏专业的支持,对于像Java这样的开源平台来说,安全性一直是一个主要问题。 而对于.NET来说,安全性是微软需要考虑的问题。微软可以为企业客户提供全天候的支持。 .NET平台的一个主要优点是微软提供了一个统一的环境。.NET平台提供了无穷无尽的水平伸缩性,你可以在微软开发者网络(Microsoft Developer Network)上获得大多数IDE和工具。

说到缺点,与其他框架相比,迁移到.NET的成本更高一些。与本机代码相比,托管代码运行得更慢。开发人员只能依赖微软提供新特性和增强。

Java的优点和缺点

Java的一个主要优点是可移植性,所以你可以根据自己的需要选择操作系统来构建应用程序或网站。

通过使用高级持续集成工具(如Jenkins和Travis CI),Java应用程序可以更好地与其他平台兼容。Java有非常壮大的社区,而且还在不断发展,提供了各种免费的集成连接器。

安全漏洞是Java平台的一个主要缺点,因为这类问题在这个平台上非常常见。

Java和.NET:选择哪个平台

无论是在IDE还是可移植性方面,Java和.NET都有一些不同的特性。但是,这两个平台的目标是一样的,而且面向的是相同的受众或细分市场,如小型公司或企业。

因此,要在这两种语言中选出一种作为项目的开发语言并不容易,因为这两种语言在各自的领域都做得很好,适合不同的项目。而且不要忘了,不管你什么时候向开发人员问起这两种语言,他们都会根据他们的偏好和技能发表不同的意见。

有哪些适合初学者学习php的网站?

我说一下我自己用过的一些网站吧。

刚开始入门的时候,我主要是在w3school里面看的php栏目,里面详细介绍了php的基础知识和概念,一般看下来就会有一个概念了。跟着教程,就能把环境搭建起来,phpinfo可以打印出来了,更好的可以写个计数器了(纯pho的)。

等基础知识都熟悉了之后,就可以去“慕课网”或者“极客学院”看视频教程,一边巩固知识,一边跟着里面的实例教程去做实际的项目,这样学习起来会更有效。

等这些视频网站的实例项目练习差不多了,就可以去csdn或者laravel-china里面其他人提的php相关的问题,然后自己试着写一写,最后再看看大牛们的想法,对比下自己的不足,学习他们的思想,他们的思路和经验很重要。

再之后就可以自己找一个全面的项目去做了,自己去设计数据库,规划功能,界面可以先不要太关注,而且现在有许多现成的前端框架模版可以直接用(比如bootstrap,amazeui等),不用担心界面会很丑。遇到不会的,就去搜索,常用的搜索网站:StackOverflow,csdn,当然最直接的就是google了(考虑到很多人没法上就没放第一位,但是装个vpn是很有必要的)。通过搜索查资料可以很快的解决你的问题的,查询的过程就是一个学习的过程,知识升华的过程。对于一些php函数或语法的使用,可以参考php官网php.net,里面详细说明了php函数和语法的使用,最最重要的,别忘了看看下面的评论,里面会有意想不到的惊喜哦!

接下来如果想再提高,就可以去github搜索一些高star的项目,看他们的源码,研究透彻,看他们为何写得好,吸收那些好的地方。然后就可以自己尝试着造轮子给其他人使用,开源出来,和大家一起讨论,一起进步。

我们来总结下上面提到的网站:

w3school学习基础,提供入门保障csdn,去学习一些php理念和思想,以及一些技巧;laravel-china虽然是laravel框架相关的分享偏多,但是里面有许多活跃的大牛,经常会分享一些经验和心得,很值得学习,这两个可以多刷刷。慕课网或者极客学院,里面有丰富的视频资源,可以更直观的学习到许多知识,而且里面有实际项目教学视频,这个是非常实用的,杜绝“纸上谈兵”。StackOverflow,一个很知名的问答社区,里面有国内外的大牛贡献的许多高质量的解答。这个也是后面需要多刷的网站。Github,程序员都知道的一个网站,也是大家共享和讨论的地方,里面有最前沿的知识和最丰富的资源,“不要重复造轮子”,如果需要用到什么,不妨先去里面搜索一下,说不定就有你想要的。当然你也可以试着造轮子供大家使用哦。 (^▽^)

这是我使用的一些网站,大家如果有什么补充的可以留言哦。

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做的也很棒。

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