本文来源于国外一位博友的文章,他在博客中写道:“是到了PHP落幕的时候了。就在我这个顽固的PHP分子正要把一个现有的Ruby on Rails代码库转换成PHP时,我要说这样的话”。

历史在重演

作者认为PHP将亡,因为我以前见到过。大概十年之前,PHP灭掉了Perl。当然了,并不十分彻底;它还坚守在某些环境里,它还有相当可观数量的顽固粉丝,遗留下来的应用程序也需要维护,持续几十年。但这种语言对于新一代的人,特别是 web开发者,它在1999年就开始灭亡了,到2005年左右几乎完全死了。

作为在那个时期出现的新的web开发者,事情显的很明白而且水到渠成:Perl已经不适应新的应用开发环境了。在Perl里,页面需要冗长的公式化的CGI方式实现,而这些在PHP里却可以用基本的、缺省的编程方式实现。Perl语言里到处都是旧时代的特征 — 引用,不方便的数据结构,还有其他许多的小的古怪语法语义 —— 这使得web开发冗长,不稳定,不方便。无怪乎没有一个出色的web应用是用Perl写成的,而用PHP你却能做的又快又简单,尽管PHP存在着在当时就显而易见的缺陷。

在1999年支持Perl反对PHP的争论有很多:Perl要快的多,有更多的程序库和驱动支持,CPAN是个神奇的地方,里面预先写好的代码能让你绝大部分任务省去80%的工作量。现在看起来这些就有点可笑了,但“PHP缺乏可扩展性”却是个真正的缺点。但总之PHP赢了,因为上面所说的这些问题并不是这种语言固有的。PHP解释器可以变得更快,程序库可以被开发出来,PERA和PECL目前已经变得相当庞大,这还不包括各种厂商希望人们去使用他们的API而提供的非正式的程序库。

时间在推移

十年之后,我可以感觉到历史大潮正在重演。开发人员对语言的期望在前进。如果说 Perl最缺乏的是PHP里令人惊讶的灵活的“关联数组”(也就是智 能哈希表),那么PHP现在缺乏的就是lambdas和方法链(method chaining)了。同时PHP往往是用在只要20行代码就能写出一个网页的地方,而如今却是如果你不使用什么MVC框架之类的东西就会被认为没有把事情做对。公式化的代码表明了问题所在:这种语言需要一个框架来替人们做这些事情。

退回到以前,我认为那些顽固的使用Perl来做web开发的人很傻。现在,经历了十年的PHP开发,我处在相同的位置上了。我可以在一个小时里用 PHP敲出一个不错的网站,在一两天里开发出一个优秀的网站。PHP的性能众人皆知,我可以无限的扩展它。我雇佣过的每个开发人员都会它,我集成过的每个系统里都有一个用它写出的打包的代码库。我深陷于PHP的方便性,尽管它对于我的任务并不是一个合适的语言。

转向Ruby on Rails

最明显有潜在能力继任PHP的是Ruby on Rails。Ruby是一个新的、干净的语言,具有现代的语言特征,松散、优雅的语法(很像Python)。Rails省去了我们常见的任务,省去了集成 web应用里的公式化的做法,把PHP里三、四行的习惯写法变成了first-class语言结构。这看起来极其像我需要的PHP替代品、能让开发工作再一次提速的东西。

我每天使用Rails,修改一个喜爱这种框架和语言的有经验的Rails专家所写的Rails应用,七个月后,我却不能断言Rails是一个正确的选择了,原因很难表达。我这篇文章的目的就是想试图把原因说清楚。

我的主要的抱怨,必须要提的,就是性能。我之前就说过这种问题不应该被当作一种语言的致命缺陷,它只是语言实现中的暂时的问题。所以我不能把这当作一个真正的问题,尽管它是我把现在的应用移植到PHP的最主要的一个原因。我可以让Rails跑的跟PHP一样快,但那需要提供2到4倍高的硬件条件。我估计五年内将还会这样,五年后我也许不必把程序移植到PHP。但现在,它不能满足我的要求。

第二,我讨厌Active Record。Active Record是一种模式,并不是Ruby固有的,在Rails的最新版本里是可选择的,但是对它的使用和这种模式已经深入到了Rails的DNA里了。我之前曾解释过为什么我认为这数据库上的ORM不是个好做法,所以我不会再重复解释,但有一点我需要总结的就是你省去了手工写CRUD所获得的效能要大于 ActiveRecord做傻事所损失的效能,要花时间搞清楚它是怎么工作的,顺应框架原则,防止它做这样的事情。

第三,我十分的不信任代码自动生成。工具能帮你生成模板式的代码很有用,但你的程序了却多出了成堆的毫无用处的代码来实现这些目的,这就变的不好了。代码生成喜欢“神奇推理”,因为生成器并不确定代码某些特别有用的特征究竟是专门写出的还是语言环境固有自带的。神奇推理是危险的。

代码生成让我想到了Ruby on Rails的一个可能是最根本的问题,就是它并不是一种语言。Ruby是一种语言。但Ruby,它在解决了PHP上的一些基本问题外,并没有解决核心问题,那就是现代web应用需要一系列的改进:像routing,model/view分类,drop-in功能性等都是很常见的特征。Rails里有,但这跟PHP里的Zend,Symfony 和 Code Igniter之类的MVC框架一样只是绑上去的绷带。

那么缺的是什么?

能够取代PHP的语言必须十分优秀于PHP,就如同PHP优秀于Perl一样。它必须承担起web应用的主要实现任务,就像PHP那样,你的代码的 主要功能就是输出网页 —— 一个有点激进的要求,它要不适合去做其它的事情,例如当中shell脚本语言。我希望有这样一种语言,它能够承担起我开发一个MVC式的web应用时的所有的任务,所有功能都是核心内置的,不能仅是一个程序包。

问题是,没有这样的一种语言。有一段时间服务器端JavaScript看起来将会成为下一个重要的语言,它能统一web应用前端和后端的编程语言。但是这些JavaScript上的伟大思想总是徘徊在一些跑题的行为上,比如 nodejs:事件驱动模式非常的激进和强大,能让你开发出高性能的应用程序,最大化的使用新式硬件,但这是一种开发服务器端应用程序的思路,不是web 页面。并且你仍然需要去写一大堆可怕的web页面。另外一些CommonJS的成果例如ejScript开始尝试着取代PHP,但仍没有解决框架问题。

仍在等待

我不得不做出结论,PHP的替代者还不存在。Ruby on Rails很好,但并不比一个PHP之上的类似的MVC框架强多少,更别提由于Ruby自身的效率不高和ActiveRecord的ORM恶搞带来的双重打击。Python看起来并不感兴趣于作为下一代的web语言,JavaScript的服务器端解决方案还刚刚只是个开始。

我等待下一个大目标的出现。我希望能从PHP上转走,真的。我可不想成为Perl式的古董。但不管怎样,这种语言看起来还不存在。我判断错了吗?

posted @ 2011-07-25 16:33 小马歌 阅读(254) | 评论 (0)编辑 收藏
 

在2010年的QCon北京大会上,记者对杨卫华进行了采访,其中谈到了关于新浪微博系统平台应对各种问题的解决方案,以及正在开发中的新浪云。

  杨卫华,新浪产品部技术经理,目前工作以新浪微博技术平台为主,曾负责过新浪IM等通讯服务端架构设计。对互联网后端技术,分布式,网络编程,XMPP即时通讯等领域感兴趣。曾组织多次广州及珠三角技术沙龙活动。个人blog 为:http://timyang.net/

  记者:大家都知道,在美国有一个非常有名的信息分享平台叫做Twitter,而在中国,我们也有同样的方式,就是现在非常流行的新浪微博,它还有个非常温馨的名字,叫做围脖。而新浪微博的架构就是杨卫华先生主持开发的。

  今天我有幸采访到杨卫华先生,让他来给大家谈一谈,在新浪微博的技术架构方面,他们是如何为用户提供更好的性能、更好的服务的。

  卫华先生你好,我的第一个问题是,在新浪微博上有很多名人,名人的微博一般都是非常热的,对它们的访问量也特别高,那么对于这些微博,您采用了么样的方式来支持这种大数据量的访问呢?

  杨卫华(以下简称卫华):对于这个问题,我们做过专门的分析。因为最近新浪微博有名人扎堆的现象,我们根据这个现象,从以下几个角度来进行解决。

  首先根据中国的网络现状,比如说网通和电信,之间的网络访问速度会比较慢,我们考虑让用户能够访问就近的服务器,这样使用体验、速度都能达到要求。我们根据新浪以往的经验,在全国部署了大量服务器,这样就为微博提供了硬件上的保证。

  第二个方面,在程序优化的方面,在产品上线之前,我们进行了全方面的压力测试,如果系统在某个方面可能会出现瓶颈,比如名人的访问量比较高的话,我们就从那个角度去优化。比如说Cache是否够用,数据库访问是不是瓶颈,这方面我们预先都有对压力的估计,然后会针对那些方面去做优化。

  第三个方面,对于那些静态资源,比如图片、视频、JS脚本,我们有专业的CDN来解决的,这样就能够保证全国的用户在访问新浪微博时都能够得到比较好的体验。

  记者:现在的服务器大概都架设在哪几个部分?覆盖全国哪几个地区?

  卫华:全国基本上大部分省份都有服务器,特别是一些比较核心的节点,比如北京、上海、广州,在这些核心的节点可能部署了更多的服务器,而在其它一些二线城市、其它省份也都有部署的。

  记者:您也是为这种大数据量做了充分的准备。最近大家都知道,玉树发生地震,对于这种突发事件,我们也会把微博作为一种信息交流、信息分享的平台,大家的访问也会造成大数据量访问,那么对于这种突发事件,您在技术架构上也做了相应的准备吗?

  卫华:对,这种突发事件以及访问峰值,是微博上经常出现的现象。突发事件的访问峰值有两种,一种是可以预测的,比如说我们将来要搞的世界杯,比如春节,大家都相互拜年这种;另外一种是不可预测的,比如地震这种。对可以预测的这种,我们事先会做准备,比如说世界杯,我们要增加相关的服务器来完成。而面对这种不可预测的情况时,我们平时会有个数字,那就是我们平时的平均流量,硬件设备要比它高一定量,这样就能够应对这种峰值的请求。

  另外从程序上来说,我们可能有一些专门的机制,比如说用户发表微博,并不是一发表就存到数据库中,简单地理解,他不是这样操作的。业界中微博之类的产品都有一种机制,叫做异步机制,也就是说,在发表的时候,我会把这个信息放到消息队列里面,然后再用另外一个专门的业务处理程序来处理它。当某一时刻发表量非常大,比如说地震了,很多人都会发表,那这个时候系统依然能够有条不紊的来处理这个业务,这样子就能让我们的系统稳定运行,并具有高可用性。

  记者:也就是要对整个事务的进行有效的控制?

  卫华:对。

  记者:大家应该知道,因为有这么多的微博,有那么多名人,而且还有很多平民的、草根的微博,系统的数据量也是非常非常大的,而且还有很多很多的评论,很多很多的留言等等。那么对于这种海量存储,是不是也要做技术架构上的准备?

  卫华:对,微博这个产品从技术上来说,有一个很大的特征,就是每天用户发表特别容易,这造成每天新增的数据量都是百万级的、上千万级的这样一个量。这样你经常要面对的一个问题就是增加服务器,因为一般一台mySQL服务器,它可能支撑的规模也就是几千万,或者说复杂一点只有几百万,这样,你可能每天都要增加服务器,从而解决所你面对的这些问题。你要考虑,如果每天要加服务器,你的程序上、访问上会不会有问题,会不会间断。

  我们其实有一些优化的方法,比如说我们会考虑热点数据和冷数据,如果经常要访问的这个数据,也就是热数据,而过几天才会访问的就是冷数据,我们会把它们合并,这样就可以按这个时间来分段,也就是把热数据放在一起,冷数据放在一起,这样可以解决这个访问热点的问题。

  另外业界还有种思路,刚才说的用MySQL,我们采用Shade的技术会按时间分片,这是一种解决思路;另外还有一种解决思路,业界特别现在国外流行的一种方法,也就是NoSQL的方法。有一种比较好的产品,现在大家比较关注,叫Cassandra,就可以解决这个问题。如果我们每天要加一台服务器的话,那么我们程序、运维这些能不能跟上呢,是否有一种产品可以让你程序不需要做丝毫改动呢?Cassandra这个产品就可以帮你来解决这个问题,你只需要把服务器插进去,那它马上可以使用,那个产品内部就有这样的机制。

 记者:那样的话对我们整个产品的维护就比较方便了?

  卫华:对,这个可能就是说以后业界发展的一种方向,使用这种分布式的存储来解决这种海量增长的问题。

  记者:你觉得NoSQL的数据库和传统的关系型的数据库,那种更适合微博这种形式的网站?

  卫华:从长远来说,NoSQL这个更适合一些,特别是分布式的NoSQL,刚才我也讲了,如果能全部下来的话,那可能经常要面对这种扩充的困扰,需要的干扰,可能是说,如果要保证服务不间断,可能就会面临一种很大的挑战,NoSQL,特别是这些分布式的NoSQL产品在内部就解决了这种问题,你不用停机,就可以加服务器,加设备。

  记者:这会对我们用户造成很大的方便?

  卫华:对。

  记者:那么在性能方面,还有一种我们常采用的方式就是Cache的方式,那么在新浪微博系统里面,Cache方式有什么样的特点?

  卫华:在像微博这样的Web2.0产品里面,技术界有一种很重要的说法,Cache就是RAM,RAM就是Memory的意思,RAM也就是New Disk,内存已经成为新的磁盘,代替磁盘的访问了。当我们大量使用Cache的时候,可能会存在很多问题,比如很多那种Web2.0的产品,它在Cache的数量已经不是G的概念了,不是几G、4G、8G的,可能达到一个TB的概念了,一个T相当于1024G,面对这样海量的数据,那我们访问的时候可能就会出现很多新的问题,比如我们的带宽,因为用户请求我的首页的时候,他会获取很多资源,比如有50个人关注你的微博,他需要从Cache里面把这50个人的数据都聚合起来,同时还会有很多人也在访问这个服务器,假如说,有一千个人访问,这一千个人里面,每个人都从五十个里面选,那么这个Cache的带宽将是一个比较大的问题,这是以前那种我们使用Cache时没有遇到过的。然后,为了解决这个带宽的问题,我们可以使用压缩的技术,我们保持Cache里面的数据,经过一种快速的压缩算法,比较传统的我们可以使用GZip,那实际上在这种对时效性要求比较高的技术里面,我们是要求更快速的算法,比如说有一些DOZO算法,它对CPU消耗很小,但它压缩很快,效果也非常好。

  另外的一个新问题,单点故障,我们非常依赖那个Cache,假如某个时候它突然崩溃了,那么应用访问可能就会遇到很大的问题,也就是响应速度会出问题,为了解决这个问题,我推荐的做法是,使用一致性的哈希算法,就说送我一个业务,他可以用多个Cache服务器来完成,然后我们使用一致性的哈希算法,当一个Cache崩溃之后,它的请求就可以分散到其它的Cache来完成,总体的那个振荡不会太大,也就是说这个延迟会分散开来,让用户访问页面的时候感觉不到,实际上后台它可能有一台服务器,刚才经历一次Crash,可能造成一次波动,经过我们这样改造之后,用户可能察觉不到这种变化。

  记者:用其它的服务器,同时来弥补这个地方的失误?

  卫华:对,使用一致性的哈希算法,能够巧妙地达到这个目的。

  记者:您刚才提到了NoSQL,另外在最近的业界还有一个流行的词就是Cloud,云计算,我们是不是有计划以后会把微博系统推广到云平台上,或者说采用云计算的方式来处理呢?

  卫华:没错,我们微博现在有一部分跟云计算结合比较密切,我们现在微博正打算推出一个开放平台,开放平台什么意思呢?就是说,第三方的开发者可以在我们上面写应用,可以连接到新浪微博,比如说可以获取信息,可以发表微博,而这些应用程序,可以放在我们的开发的另外一个服务上,叫新浪云。这个新浪云有什么好处呢?这些第三方开发的应用,可能他刚开发的时候,请求量不大,但有可能因为这个创意很好,忽然访问量大了。如果你用你自己的解决方案的话,可能就达不到这种要求。比如说最大的问题,可能就是全国访问不畅,或者访问量突然增长了,原来的服务器不够用,你要自己去加硬件,来不及处理。如果你放在那个新浪云上面的话,那我们系统自动会帮你解决这个问题,不管你的一个非常小的程序,比如一天只有几百个访问,还是一个海量的应用,我们都能够放在这个平台里面。在这个云应用里面,你不需要自己操心,系统自动会帮你把这个任务完成。另外它还有一个好处就是,这个云自动实现了全国分布,你只要Host在上面,全国的用户不管从哪里访问,他可以访问一个就近的服务器,这在速度比自己部署都具有很大的优势。

  记者:那咱们新浪云现在已经正式推出来,还是正在计划中?

  卫华:我们现在还处于测试阶段,我们采用一种邀请式,希望邀请更多的开发者来试用它,我们根据开发者的反馈来改善它,等到一定程度,我们再去大规模地推广。

  记者:以后对于大家来维护自己的微博、访问别人微博,是不是也更方便,不一定非要到各种各样的网页上,或者是手机等等,可以在自己开发的程序上就可以做这些事了,对吧?

  卫华:对,以后结合这个微博的开放平台,结合新浪云,可以形成一个良好的生态圈,第三方的开发者要有一个很好的环境,给微博增加各种创意,增加各种应用。

  记者:这应该是对开发者带来的一个福音。

  卫华:对。

  记者:感谢杨卫华先生接受我们的采访。谢谢!

posted @ 2011-07-25 16:24 小马歌 阅读(364) | 评论 (0)编辑 收藏
 
     摘要: 注意:以下代码请在Firefox 3.5、Chrome 3.0、Safari 4之后的版本中进行测试。IE8的实现方法与其他浏览不同。 跨域请求,顾名思义,就是一个站点中的资源去访问另外一个不同域名站点上的资源。这种情况很常见,比如说通过 style 标签加载外部样式表文件、通过 img 标签加载外部图片、通过 script 标签加载外部脚本文件、通过 Webfont 加载字体文件等等。...  阅读全文
posted @ 2011-07-25 16:22 小马歌 阅读(3119) | 评论 (0)编辑 收藏
 
     摘要: 来自:http://www.cnblogs.com/leoo2sk/archive/2011/04/19/nginx-module-develop-guide.html前言Nginx是当前最流行的HTTP Server之一,根据W3Techs的统计,目前世界排名(根据Alexa)前100万的网站中,Nginx的占有率为6.8%。与Apache相比,Nginx在高并发情况下具有巨大的性能优势。Ngi...  阅读全文
posted @ 2011-07-25 12:17 小马歌 阅读(955) | 评论 (0)编辑 收藏
 

这里我们通过一个简单的HelloWorld项目演示Air项目的开发过程,本文演示的是在Windows操作系统下,使用HTML技术来开发Air应用的过程,在不同操作系统下,使用不同的开发技术(比如:flash/flex)开发过程可能会略有不同。

建立开发环境

一个完整的Air开发环境需要安装AirRuntimeAirSDKJavaRuntime,总体来说安装与配置过程还是比较简单的。其中AirRuntimeJavaRuntime的安装非常简单,我们只需要下载,并执行下载文件安装即可,和安装一个普通的应用程序没什么两样,下载地址:

AirRuntimehttp://get.adobe.com/cn/air/

JavaRuntimehttp://www.java.com/zh_CN/

需要说一下的是AirSDK的安装,首先我们要下载它:http://www.adobe.com/products/air/tools/sdk/

下载后我们会得到一个AdobeAIRSDK.zip文件,您可以将它解压到任何一个目录下,例如解压到“D:/AirSDK/”。解压后只需要在path环境变量中加入“D:/AirSDK/bin”。这样,我们的开发环境就搭建好了,下面让我们来开发应用程序吧。

编写应用程序

每一个Air应用都需要一个应用程序配置文件(以下称为:项目描述文件),这个文件使用XML格式,用于配置项目相关的信息,比如程序入口,初始窗体的一些设置等。Air运行时框架也是通过此文件才能得知应用程序的入口信息。

在这个程序配置文件中我们可以指定应用程序入口HTML文件,这样,我们就可以通过这个HTML文件来开启Air应用之旅。下面我们将制作一个Air应用,整个应用由“application.xml”、“HelloWorld.html”两个文件组成。我们先来看看项目描述文件。

创建项目描述文件

我们先来建立一个目录来存放Air应用的文件,比如:“D:/airApps/HelloWorld”。在HelloWorld建立一个application.xml文件,其内容如下:

<?xml version="1.0" encoding="UTF-8"?>

<application xmlns="http://ns.adobe.com/air/application/1.5">

<id>com.keda.examples.HelloAir</id>

<version>0.1</version>

<filename>HelloAir</filename>

<initialWindow>

        <content> HelloWorld.html</content>

        <visible>true</visible>

        <width>400</width>

        <height>200</height>

</initialWindow>

</application>

简单解释一下:

1.         <application> 元素,包括 AIR 命名空间属性:

<application xmlns="http://ns.adobe.com/air/application/1.5"> 该命名空间的最后一部分“1.5 指定了应用程序所需的运行时版

本。

2.         <id> 元素:

<id>examples.html.HelloWorld</id> 应用程序 ID 与发布者 ID AIR 从对应用程序包进行签名时使用的证书中获取)一起

可以标识唯一的应用程序。建议采用的形式为以点分隔的反向 DNS 样式的字符串,如 "com.company.AppName"。应用程

 ID 可用于安装、访问专用应用程序文件系统存储目录、访问专用加密存储以及应用程序间的通信。

3.         <version> 元素:

<version>0.1</version> 可帮助用户确定安装哪个版本的应用程序。

4.         <filename> 元素:

<filename>HelloWorld</filename> 用于操作系统中应用程序可执行文件、安装目录和对应用程序的其它引用的名称。

5.         包含下列子元素的 <initialWindow> 元素,为初始应用程序窗口指定属性:

<content>HelloWorld.html</content> 标识 AIR 要加载的根 HTML 文件。

<visible>true</visible> 使窗口立即可见。

<width>400</width> 设置窗口宽度(以像素为单位)。

<height>200</height> 设置窗口高度。

创建入口HTML页面

新建“HelloWorld.html”内容如下:

<html>

<head>

<title>Hello World</title>

</head>

<body >

<h1>Hello World</h1>

</body>

</html>

HTML很简单,这里不多说了。到这里我们的Air应用就编写完成了,下面让我们调试运行一下。

调试运行Air应用

Dos命令行下进入“D:/airApps/HelloWorld”,然后使用adl命令进行高度。命令如下:

adl application.xml

看看运行结果:

 

打包和分发

Air应用打包之前需要Air的证书,Air证书有两种,一种是Air颁发的,另一种是自签名证书,这种证书我们可以直接通过命令行生成并使用,自签名证书打包的应用在安装时不会显示机构名称,如下图所示:

 

但作为学习自签名证书还是比较适用的,下面简介一下自签名证书的生成。

 

生成证书

命令格式说明:adt -certificate -cn name [-ou org_unit][-o org_name][-c country] key_type pfx_file password

-cn name 分配的作为新证书公共名称的字符串。

-ou org_unit 分配的作为证书颁发组织单位的字符串。(可选。)

-o org_name 被分配作为证书颁发组织的字符串。(可选。)

-c country 双字母 ISO-3166 国家地区代码。如果提供的代码无效,则不会生成证书。(可选。)

key_type 用于证书的密钥类型,即“1024-RSA 或“2048-RSA”。

pfx_file 证书文件的生成路径。

password 新证书的密码。当使用此证书对 AIR 文件签名时需要提供密码。

例如本程序证书使用以下命令生成:

adt -certificate -cn HelloWorld -ou it.kedacom.com -o KEDACOM 2048-RSA HelloWorld.p12 kedacom

打包分发

证书生成之后我们就可以进行打包了,

adt –package -tsa none -storetype pkcs12 -keystore HelloWorld.p12 HelloWorld.air application.xml HelloWorld.html

系统将提示您输入生成证书时的密码:kedacom

HelloWorld.air 参数表示 ADT 生成的 AIR 文件。HelloWorld-app.xml 表示应用程序描述符文件。后面的参数表示应

用程序所使用的文件。此示例仅使用了两个文件,但可以包含任意数量的文件和目录。

至此,我们的应用就已经完成了,您可以通过双击生成的.air安装包来安装我们的应用。

用命令行工具进行打包还是比较繁琐的,推荐使用Aptana Studio来开发Air应用,项目创建、证书的生成、打包都有图形化工具可以使用。

Aptana Studio下载地址:http://www.aptana.org/studio/download

posted @ 2011-07-22 16:39 小马歌 阅读(555) | 评论 (0)编辑 收藏
 

gmail 邮件中css无效style无效background image背景图片无效不显示的解决办法

几乎每个会员制网站都需要通过后台发送邮件来与会员进行沟通,如注册确认、营销推广。这些由站方发给会员的信件,往往纯
文本格式已不能满足界面和交互的要 求,这时候我们就需要发送HTML页面。由于HTML邮件不是独立的HOST在本站的页面,是寄人篱下的。所以编写HTML邮件与编写HTML页面有很大 的不同。因为,各面向网民的主流邮箱都或多或少的会对它们接收到的HTML邮件在后台进行过滤。毫无疑问,JS代码是被严格过滤掉的,包括所有的事件监听 属性,如onclick、onmouseover,这是基于邮件安全性的考虑。不仅如此,CSS代码也会被部分过滤。本人要讲的就是如何编写不被各大主流 邮箱过滤的,能正常显示的HTML邮件。

gmail会自动过滤掉 head里的<style>设置的css,所以必须要把css写在html里面。

例如 <div style=”font-size:14px;”>

另外,gmail不支持在css里定义background里的image,包括background:url(”…”)和background-image:url(“..”)

解决办法是 在div的外面加上一层  <table>和<td>

并在<td>里加上background属性,例如

<table>

<tr>

<td  background=”http://www.vivizu.com/test.jpg”>

<div>test</div>

</td>

</tr>

</table>

呵呵 ,就可以看到背景图片了

posted @ 2011-07-13 14:14 小马歌 阅读(673) | 评论 (0)编辑 收藏
 

1、停止MYSQL服务器:
      /etc/init.d/mysql stop或service mysqld stop

2.  cd /etc/init.d/

(3)跳过授权表执行MYSQL服务器:

               mysqld_safe --skip-grant-tables --skip-networking &
        (注:参数--skip-grant-tables为跳过授权表;--skip-networking为不监听TCP/IP连接)

     [root@speedec init.d]#  mysqld_safe --skip-grant-tables --skip-networking &
    [1] 28135
    [root@speedec init.d]# Starting mysqld daemon with databases from /var/lib/mysql

    在此可以Ctrl+C终止

(4).启动mysql

[root@speedec init.d]# mysql

(5)使用mysql数据库

 mysql> use mysql;

(6)更新root密码
         update user set password=password('新密码') where user='root';

7.重启mysql

service mysqld stop

service mysqld start

posted @ 2011-07-12 10:12 小马歌 阅读(223) | 评论 (0)编辑 收藏
 
作者:老王

在动手操作前最好先安装好MySQL-Proxy,并配置好MySQL主从服务器。补充:新版MySQL已经内建支持

延迟问题

读写分离不能回避的问题之一就是延迟,可以考虑Google提供的SemiSyncReplicationDesign补丁。

端口问题

MySQL-Proxy缺省使用的是4040端口,如果你想透明的把3306端口的请求转发给4040的话,那么可以:

iptables -t nat -I PREROUTING -s ! 127.0.0.1 -p tcp --dport 3306 -j REDIRECT --to-ports 4040

如果想删除这条规则,可以把上面例子中的-I换成-D。

参考链接

密码加密方式

MySQL-Proxy不支持老的密码加密方式,所以如果你使用的是老版本的MySQL,或者启用了old_passwords选项的话,则可能会出现错误:

ERROR 2013: Lost connection to MySQL server

此时最好的修复方法就是使用新的密码加密方式,如果你的用户表是老式的,可能需要先运行MySQL源代码里scripts目录下的mysql_fix_privilege_tables脚本升级表结构。有时候客观情况可能不允许立刻进行升级操作,此时可以为MySQL-Proxy专门建立一个密码为空的用户(通过主机限制访问,或者起一个很复杂的用户名),因为不管是新的密码加密方式还是旧的密码加密方式,空密码都同样是一个空字符串,这样就规避了密码加密的问题。

查询乱码

连接上MySQL-Proxy后,执行查询时,随机出现乱码。出现此问题的原因是当我们使用MySQL-Proxy读写分离时,通常会有多个后端服务器,客户端发出查询请求时,一般会先发出一条类似"SET NAME gbk"的语句来声明客户端编码,然后再发出实际查询的SQL语句,但MySQL-Proxy可能会把这两条语句分发给不同的后端服务器,于是就出现了乱码。

解决方法是强行指定后端服务器的字符编码:

init-connect='SET NAME gbk'

default-character-set=gbk
skip-character-set-client-handshake

如果使用init-connect,则需要注意操作用户不能有SUPER权限,否则此选项无效。

即便做好了以上的设置后,还有可能会出现乱码,比如说数据库是gbk的,当我们用PHPMyAdmin连接MySQL-Proxy时,查询还是会出现乱码,不过这是正常的!因为PHPMyAdmin使用的是utf8编码,它发出的“SET NAMES utf8”语句被skip-character-set-client-handshake屏蔽了,所以出现乱码。

进程崩溃

MySQL-Proxy偶尔会出现进程崩溃的情况,具体原因不明。

新版的MySQL-Proxy为了应付这个问题加入了一个keepalive选项(try to restart the proxy if it crashed),当使用这个选项时,会先后启动两个mysql-proxy进程,先启动的mysql-proxy进程用来监控后启动的mysql-proxy进程,实际提供服务的是后启动的mysql-proxy进程,一旦后启动的mysql-proxy进程挂掉(你可以自己kill试试),先启动的mysql-proxy进程会重新启动一个mysql-proxy提供服务。

不过现在很多人用的还是旧版的MySQL-Proxy,此时可以利用init来实现类似keepalive的效果:

编写脚本/usr/local/sbin/mysql-proxy.sh,加入以下内容(具体写法视安装情况而定):

LUA_PATH="/usr/local/mysql-proxy/share/mysql-proxy/?.lua" \
/usr/local/mysql-proxy/sbin/mysql-proxy \
--proxy-backend-addresses=192.168.0.1:3306 \
--proxy-read-only-backend-addresses=192.168.0.2:3306 \
--proxy-lua-script=/usr/local/mysql-proxy/share/mysql-proxy/rw-splitting.lua

别忘了加上可执行属性:

chmod a+x /usr/local/sbin/mysql-proxy.sh

0.7.0版本有一个新的选项:--defaults-file,可以把相关信息都写到配置文件里:

# MySQL Proxy's configuration file (mysql-proxy.cnf)

[mysql-proxy]
daemon = true
keepalive = true
proxy-backend-addresses = 192.168.0.1:3306
proxy-read-only-backend-addresses = 192.168.0.2:3306
proxy-lua-script = /usr/local/mysql-proxy/share/mysql-proxy/rw-splitting.lua

启动时可以使用:mysql-proxy --defaults-file=mysql-proxy.cnf

修改inittab:

vi /etc/inittab

加入以下内容:

mp:12345:respawn:/usr/local/sbin/mysql-proxy.sh

然后让init重新读取inittab内容:

kill -HUP 1

系统会自动检测/usr/local/sbin/mysql-proxy.sh是否正在运行,如果没有就自动运行。

需要注意的是在编写mysql-proxy.sh脚本的时候,不要加入--daemon选项,否则/usr/local/sbin/mysql-proxy.sh一运行就结束了,系统会不停的尝试运行脚本,从而在/var/log/message里留下大量的错误信息(init: Id "mp" respawning too fast: disabled for 5 minutes)。

init的方法可能显得有点另类了,可以使用其他的工具,比如svscan

有状态的查询

一些有状态的特殊的查询可能失效,比如说:

SELECT SQL_CALC_FOUND_ROWS ..
SELECT FOUND_ROWS()

这种查询是有状态的,应该保证在同一个后端处理,查看rw-splitting.lua脚本可以看到MySQL-Proxy实际上已经对这样的查询进行了 判断,但在实际应用中发现还是存在问题。估计是脚本写得不咋地,实际应用中,建议大家不要使用这样的查询,一来没有可移植性,而来效率也不见得好。

另一个可能会产生问题的查询是:

INSERT ... (AUTO_INCREMENT)
SELECT LAST_INSERT_ID()

当系统执行完INSERT后,再执行SELECT时,可能已经被分发到了不同的后端服务器,如果你使用的编程语言是PHP的话,此时应该通过 mysql_insert_id()来得到最新插入的id,每次INSERT结束后,其实对应的autoincrement值就已经计算好返回给PHP 了,你无需再发出一次独立的查询,直接用mysql_insert_id()就可以了。不过很多PHP程序使用的都是SELECT LAST_INSERT_ID()的方式,如AdbDB,CakePHP等等,如果你正在使用它们的话需多加小心。(当使用bigint 时,mysql_insert_id()存在问题,详情见手册,不过对于大多数人而言,bigint基本不会遇到,所以你可以无视这个问题)

注:对于这两个问题,官方BUG库里有人给出了相应的补丁

脚本问题

MySQL-Proxy读写分离的功能是通过lua脚本(rw-splitting.lua)实现的,但是这个脚本年久失修,问题多多,比如说使用时可能会出现:

ERROR 1105: can't change DB to on slave

出现这个问题的原因在于当客户端发出查询时,MySQL-Proxy会比较当前客户端所处数据库和服务器所处数据库是否一致,如果不一致则会在服务端尝试执行一个"USE 数据库"的操作,一个可能性是主从服务器的数据库结构不同,在USE一个不存在的数据库的时候自然会出错,还有一个原因有些查询操作并没有所处数据库这个上下文,比如说SHOW DATABASES这个查询,并不需要事先“USE 数据库”,只要连上服务器就可以执行,这时候如果还尝试同步客户端和服务端所处的数据库,出错就是无法避免的事了。

rw-splitting.lua恰恰没有屏蔽后者所描述的情况,修复方法如下,在合适的位置加入粗体代码,

276         if cmd.type ~= proxy.COM_INIT_DB and
277            c.default_db and c.default_db ~= "" and c.default_db ~= s.default_db then
if is_debug
278                    print("    server default db: " .. s.default_db)
279                    print("    client default db: " .. c.default_db)
280                    print("    syncronizing")
end
281                 proxy.queries:prepend(2, string.char(proxy.COM_INIT_DB) .. c.default_db)
282         end

在lua中,~=是不等于的意思,另外,lua里空字符串""用在if里被认为是true,所以单靠c.default_db不够。

顺手加上is_debug的判断,不然即使不是debug状态,服务器的命令行里也会偶尔冒出一些调试信息。

此外,新版MySQL-Proxy里,虽然源代码包里有rw-splitting.lua脚本,但缺省并没有安装,你需要手动拷贝,而且数据结构发生了变化,脚本需要按照数据结构的变化做出适当的修改,可以参考作者的描述操作,或者参考官方Bug管理或者直接下载。值得期待的是现在有了专门的MySQL-Proxy-Lua-Scripts项目,希望开发进度能跟上来。
posted @ 2011-07-07 18:50 小马歌 阅读(341) | 评论 (0)编辑 收藏
 
     摘要: 一,mysql proxy是什么,干什么用的MySQL Proxy就是这么一个中间层代理,简单的说,MySQL Proxy就是一个连接池,负责将前台应用的连接请求转发给后台的数据库,并且通过使用lua脚本,可以实现复杂的连接控制和过滤,从而实现读写分离和负 载平衡。对于应用来说,MySQL Proxy是完全透明的,应用则只需要连接到MySQL Proxy的监听端口即可。当然,这样proxy机器可...  阅读全文
posted @ 2011-07-07 17:40 小马歌 阅读(663) | 评论 (0)编辑 收藏
 
     摘要: 一,先说一下为什么要分表当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。根据个人经验,mysql执行一个sql的过程如下:1,接收到sql;2,把sql放到排队队列中 ;3,执行sql;4,返回执行结果。在这个执行过程中最花时间在什么地方呢?第一,是排队等待的时间,第二,sql的执行时间。其实这二...  阅读全文
posted @ 2011-07-07 17:40 小马歌 阅读(225) | 评论 (0)编辑 收藏
仅列出标题
共95页: First 上一页 50 51 52 53 54 55 56 57 58 下一页 Last