<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>وبلاگ شخصی علی فرهادی</title>
	
	<link>http://farhadi.ir/blog</link>
	<description>The daily thoughts and work experiences of a web developer</description>
	<lastBuildDate>Fri, 04 Mar 2011 11:42:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>fa</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/farhadi" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="farhadi" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>چرا node.js اینقدر طرفدار داره</title>
		<link>http://farhadi.ir/blog/1389/09/23/why-nodejs-is-so-popular/</link>
		<comments>http://farhadi.ir/blog/1389/09/23/why-nodejs-is-so-popular/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 10:53:52 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[توسعه‌ی وب]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=288</guid>
		<description><![CDATA[
به جرأت میتونم بگم node.js انقلابی‌ترین حرکت در زمینه توسعه وب توی یکی دو سال گذشته بوده. node در github سومین پروژه از لحاظ محبوبیته و همین الان که من دارم این مطلب رو می‌نویسم این پروژه بیش از 4000 تماشاچی داره و بیش از 400 بار fork خورده و 100 ها ماژول براش نوشته [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-291  alignright" title="nodejs" src="http://farhadi.ir/blog/wp-content/uploads/2010/12/nodejs.png" alt="nodejs" width="200" height="53" /></p>
<p>به جرأت میتونم بگم <a href="http://nodejs.org/" target="_blank">node.js</a> انقلابی‌ترین حرکت در زمینه توسعه وب توی یکی دو سال گذشته بوده. <a href="https://github.com/ry/node" target="_blank">node در github</a> سومین پروژه از لحاظ محبوبیته و همین الان که من دارم این مطلب رو می‌نویسم این پروژه بیش از 4000 تماشاچی داره و بیش از 400 بار fork خورده و 100 ها ماژول براش نوشته شده و همه این اتفاقات در کمتر از یک سال و اندی که از شروع این پروژه می‌گذره افتاده.</p>
<p>اگر اخبار و تحولات توسعه وب رو دنبال کرده باشید حتما تا به حال مطالبی در موردش شنیدید اما ممکنه به اهمیت موضوع پی نبرده باشید. به عبارت دیگه اکثر افراد در وهله اول متوجه نمیشن که node چه چیز جدیدی برای ارائه داره و چی باعث محبوبیت اون شده.</p>
<p>اگر می‌خواهید در مورد node بیشتر بدونید در ادامه این مطلب با من همراه باشید.</p>
<p><span id="more-288"></span></p>
<p><strong>حالا این node.js چی هست؟ یک فریم ورک جدید مثل jquery؟</strong></p>
<p>نه اشتباه نکنید. node.js هیچ ربطی به مرورگر نداره و کدی که برای node نوشته میشه قرار نیست روی مرورگر اجرا بشه.</p>
<p><strong>پس لابد یک زبان برنامه نویسی جدیده!</strong></p>
<p>زبان جدید هم نیست. برنامه‌های node به زبان جاوا اسکریپت نوشته میشن. جاوا اسکریپتی که سمت سرور اجرا میشه. البته از node میشه برای نوشتن برنامه‌های غیر سروری هم استفاده کرد ولی بیشتر کاربردش برای نوشتن برنامه‌های سروری مخصوصا وبسرورهاست.</p>
<p><strong>پس node رو میشه مثل php و python روی وبسرور نصب کرد.</strong></p>
<p>نه. node مستقله. در واقع node خودش وبسرور داره و از وبسرور فعلی شما (مثلا آپاچی) استفاده نمیکنه.</p>
<p><strong>میشه دقیقتر توضیح بدی یک برنامه تحت وب با node چه جوری اجرا میشه؟</strong></p>
<p>node از طریق خط دستور (command line) اجرا میشه و برنامه شما رو اجرا میکنه. حالا برنامه شما میتونه از ماژول وبسرور node استفاده کنه و یک وبسرور راه بندازه.</p>
<p><strong>ولی من هر کاری که بخوام با php و python و ruby و &#8230;  میتونم انجام بدم.</strong></p>
<p>خوب آره. node هم قرار نیست کار جدیدی که قبلا غیر ممکن بوده رو انجام بده.  قرار هم نیست جای php و python و &#8230; رو بگیره. حداقل هنوز نه.</p>
<p><strong>خوب پس چی باعث شده اینقدر طرفدار پیدا کنه؟</strong></p>
<p>دلایل مختلفی داره. اگر ایده و هدف اصلی node و نحوه کارش رو بدونید خیلی از دلایلش مشخص میشه.</p>
<p>هدف node ایجاد راهکاری آسان برای نوشتن برنامه‌های مرتبط با شبکه با سرعت، کیفیت و مقیاس پذیری بالاست. پس دلیل اول محبوبیت node رو میشه این جوری نوشت که با node حتی برنامه‌نویس‌های غیرحرفه‌ای هم می‌تونن برنامه‌های حرفه‌ای برای شبکه بنویسند.</p>
<p><strong>مگه node چه جوری کار میکنه؟</strong></p>
<p>سوال خیلی خوبیه. برای اینکه به این سوال جواب بدیم اول باید ببینیم که بقیه وبسرورها چه جوری کار می‌کنند.</p>
<p>معمولا وبسرورها اینجوری کار می‌کنند که به ازای هر کانکشن یک thread جدید می سازند و این thread تا زمانی که کانکشن مربوطه باز باشه باقی می‌مونه. این کار بار پردازشی و مصرف مموری اضافی برای هر کانکشن ایجاد میکنه و به عبارتی باعث میشه تعداد کلاینت هایی که یک وبسرور همزمان میتونه پاسخگو باشه محدود باشه، عددی که به 10 هزار نمیرسه. برای همین این مشکل با نام «<a href="http://www.kegel.com/c10k.html" target="_blank">مسئله 10 هزار کانکشن همزمان</a>» یا C10K معروفه. البته این مسئله‌ی جدیدی نیست. بحث سر این مسئله و راهکارهای موجود از حدود 11 سال پیش وجود داشته. وبسرورهای جدید نظیر <a href="http://nginx.org/" target="_blank">nginx</a> و <a href="http://www.lighttpd.net/" target="_blank">lighttpd</a> و <a href="http://www.cherokee-project.com/" target="_blank">cherokee</a> این مشکل رو حل کردند. و البته node.js هم با توجه به هدف اولیه ای که داشته جزو اون دسته از وبسروهایی محسوب میشه که این مشکل رو ندارند.</p>
<p><strong>و این مشکل چطور حل شده؟</strong></p>
<p>قبل از اینکه به راه حل مشکل بپردازیم باید ببینیم مشکل از کجا ناشی میشه.</p>
<p>مشکل از اونجایی ناشی میشه که دریافت، پردازش و پاسخ دادن به یک درخواست از یک کلاینت اونقدر طول میکشه که نمیشه برای دریافت کانکشن بعدی منتظر اتمام کار کانکشن قبلی موند. بنابراین وبسرورها برای پاسخ به کلاینت جدید یک thread جدید ایجاد می‌کردند.</p>
<p><strong>خوب پس مشکل اصلی در واقع کند بودن روند دریافت، پردازش و پاسخ  هست.</strong></p>
<p>دقیقا. اما مسئله اینجاست که پردازنده ها به اندازه کافی سریع هستند و اون چیزی که باعث کند شدن این روند میشه I/O هست. یعنی عملیات ورودی و خروجی، چه از شبکه و چه از سیستم فایل.</p>
<p><strong>اونوقت مشکل IO رو چطور حل کردند؟</strong></p>
<p>برای رفع این مشکل به جای اینکه عملیات ورودی/خروجی مستقیما انجام بشه از معماری رویداد گرا برای پیاده سازی IO استفاده میشه. به عبارتی به جای اینکه منتظر نتیجه IO بمونیم یک رویداد برای دریافت نتیجه تعریف می‌کنیم و اجرای برنامه ادامه پیدا میکنه. به این ترتیب عملیات های ورودی/خروجی باعث بلاک شدن اجرای برنامه نمیشه. و node هم با همین معماری نوشته شده برای همین اولین جمله ای که در توصیف node در سایتش نوشته شده اینه: «Evented I/O for V8 JavaScript»</p>
<p><strong>اگر وبسرورهایی مثل nginx قبلا این مشکل رو حل کردند پس node چه حرفی واسه گفتن داره؟</strong></p>
<p>درسته که این مشکل قبلا حل شده ولی این مشکل فقط در سطح وب سرور حل شده. منظورم اینه که مثلا وقتی میخوای یک برنامه php رو روی این وبسرور اجرا کنی با اینکه وبسرور برای هر درخواست thread ایجاد نمیکنه ولی php این کار رو میکنه.</p>
<p><strong>پس با این حساب node راهکاری برای برنامه نویسی رویداد گرای IO سمت سرور فراهم کرده.</strong></p>
<p>درسته. البته node اولین نیست. قبل از node این سبک برنامه نویسی با <a href="http://twistedmatrix.com/trac/" target="_blank">Twisted</a> در python و <a href="http://rubyeventmachine.com/" target="_blank">EventMachine</a> در ruby هم امکان پذیر بوده. خود برنامه نویس node هم گفته که توی طراحی node از این دو پروژه ایده گرفته.</p>
<p><strong>پس چرا اونها به اندازه node معروف نشدند؟</strong></p>
<p>دلایل مختلفی داره.</p>
<p>یکی اینکه برنامه های node به زبان جاوا اسکریپت نوشته میشن. و اکثر کسانی که تو کار توسعه وب هستند کم و بیش با این زبان آشنایی دارند. علاوه بر این زبان جاوا اسکریپت زبان فوق العاده ای برای معماری رویداد گراست و اکثر کسانی که قبلا با جاوا اسکریپت برای مرورگر کد نوشتند برنامه نویسی رویداد گرا با جاوا اسکریپت رو تجربه کردند.<br />
یک مزیت دیگه جاوا اسکریپتی بودن اینه که برای برنامه نویسی سرور و کلاینت از یک syntax استفاده میشه که قطعا راحت تره و حتی بخش‌هایی از کد رو برای هر دو طرف میشه استفاده کرد (مثل اعتبار سنجی فرمها).<br />
دیگه اینکه node برای موتور جاوا اسکریپت از <a href="http://code.google.com/p/v8/" target="_blank">V8</a> استفاده میکنه که جزو  سریعترین مفسرهای اسکریپتی محسوب میشه و حتی از پایتون هم سریعتره.<br />
دلیل دیگه اینه که node از اول با این ایده یعنی رویداد گرا طراحی شده نه به صورت یک library جداگانه، بنابراین کار باهاش خیلی راحت تره.</p>
<p><strong>ولی به درد من نمی‌خوره. من هیچ وقت 10 هزار تا بازدیدکننده همزمان ندارم. مشکلی هم با سرعت برنامه هام ندارم.<br />
</strong></p>
<p>مسئله فقط سرعت و مقیاس پذیری نیست.</p>
<p>برای مقایسه یک برنامه php رو در نظر بگیرید. هر بار که یک درخواست به سرور ارسال میشه برنامه php اجرا میشه و یک نتیجه ای رو بر میگردونه و تموم میشه. ولی برنامه ای که با node نوشته شده یکبار اجرا میشه و تو حافظه می‌مونه. اینجا به جای اینکه وب‌سرور برنامه رو اجرا کنه این برنامه هست که وب‌سرور رو اجرا می‌کنه. بنابراین برنامه به همه کانکشن‌های سرور دسترسی داره و مثلا میتونه اطلاعاتی رو از یک کلاینت بگیره و به یک کلاینت دیگه بفرسته بدون اینکه از دیتابیس یا shared memory استفاده کنه. برای مثال با این ویژگی میشه بدون استفاده از دیتابیس و یا هیچ ابزار جانبی دیگه ای یک چت روم نوشت.<br />
یک مثال دیگه از قابلیت‌های node حالتیه که برای همه درخواست ها احتیاج به یکسری اطلاعات مشترک داریم که باید از دیتابیس خونده بشه. با php یا باید همه اطلاعات هر بار از دیتابیس خونده بشه و یا اینکه یکبار کش بشه و دفعات بعد از کش خونده بشه. ولی با node میشه این اطلاعات رو یکبار خوند و برای همه کانکشن ها ازش استفاده کرد.</p>
<p>در ضمن امروزه با فراگیر شدن وب 2 استفاده از <a href="http://en.wikipedia.org/wiki/Comet_%28programming%29" target="_blank">comet</a> هم رایج تر شده. برای پیاده سازی comet در واقع یک کانکشن به سرور برقرار میشه و باز نگه داشته میشه. که با وبسروری مثل آپاچی با زیاد شدن تعداد کانکشن‌ها عملا این کار غیر ممکن میشه. ولی node برای این کار فوق العادست.</p>
<p>نکته دیگه ای که در مورد node وجود داره تعدد ماژول هاشه. تقریبا توی هر زمینه ای که بخواهید برای node ماژول پیدا میشه.</p>
<p>برای نمونه <a href="http://socket.io/" target="_blank">socket.io</a> ماژولی برای پیاده سازی ارتباط دو طرفه بین سرور و مرورگر هست. این ماژول برای پیاده سازی comet تقریبا از همه روش‌های موجود نظیر Ajax long pulling و Flash Socket و WebSocket پشتیبانی می‌کنه و بسته به اینکه مرورگر شما با کدامیک از این روش‌ها سازگار باشه خودش بهترین روش ممکن رو انتخاب می‌کنه. و تقریبا همه مرورگرهای رایج رو پشتیبانی می‌کنه.<br />
با این ماژول به راحتی میشه ارتباطات دوطرفه و بلادرنگ بین سرور و کلاینت برقرار کرد.</p>
<p>خلاصه اینکه ابزارها و ماژول های فوق العاده ای برای node نوشته شده نظیر <a href="http://expressjs.com/" target="_blank">express</a> و <a href="http://projects.nuttnet.net/hummingbird/" target="_blank">hummingbird</a> و <a href="http://vowsjs.org/" target="_blank">vows</a> و ماژولهای مختلفی برای کار با دیتابیس‌های مختلف. حتی به خاطر تعدد ماژولها برای node ابزار مدیریت بسته ها (<a href="http://npmjs.org/" target="_blank">node package manager</a>) هم نوشته شده تا نصب و بروزرسانی ماژول‌ها راحت تر باشه.</p>
<p>خوب دیگه فکر کنم همینقدر برای شروع کافی باشه.</p>
<p>برای حسن ختام چند تا لینک مرتبط هم معرفی میکنم:</p>
<ul>
<li><a href="http://debuggable.com/posts/understanding-node-js:4bd98440-45e4-4a9a-8ef7-0f7ecbdd56cb" target="_blank">Understanding node.js</a> مقاله‌ای برای معرفی node.js</li>
<li><a href="http://howtonode.org/" target="_blank">howtonode.org</a> یک وبلاگ جمعی درباره node.js</li>
<li><a href="https://github.com/ry/node/wiki/modules" target="_blank">Node Modules</a> لیستی از ماژولهای node</li>
<li><a href="https://github.com/ry/node/wiki/Hosting" target="_blank">Node Hostings</a> لیستی از میزبان‌هایی که از node پشتیبانی می‌کنند.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1389/09/23/why-nodejs-is-so-popular/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>سر و کله زدن با دیتابیس‌های حجیم MySQL</title>
		<link>http://farhadi.ir/blog/1389/08/13/dealing-with-large-mysql-databases/</link>
		<comments>http://farhadi.ir/blog/1389/08/13/dealing-with-large-mysql-databases/#comments</comments>
		<pubDate>Thu, 04 Nov 2010 00:00:51 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[متفرقه]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=259</guid>
		<description><![CDATA[توی پروژه های کوچیک و متوسط معمولا طراحی دیتابیس زیاد جدی گرفته نمیشه ولی توی پروژه های بزرگ با دیتابیس‌های حجیم دقت در جزئیات اهمیت زیادی داره و طراحی و نگهداری دیتابیس یک تخصص جداگانه محسوب میشه.
امروز قصد دارم اطلاعات و تجاربی رو که از سر و کله زدن با دیتابیس های حجیم بدست آوردم [...]]]></description>
			<content:encoded><![CDATA[<p>توی پروژه های کوچیک و متوسط معمولا طراحی دیتابیس زیاد جدی گرفته نمیشه ولی توی پروژه های بزرگ با دیتابیس‌های حجیم دقت در جزئیات اهمیت زیادی داره و طراحی و نگهداری دیتابیس یک تخصص جداگانه محسوب میشه.</p>
<p>امروز قصد دارم اطلاعات و تجاربی رو که از سر و کله زدن با دیتابیس های حجیم بدست آوردم رو با شما سهیم بشم. بدست آوردن  بعضی از این تجربه ها  ممکنه واقعا گرون تموم بشه.</p>
<p><span id="more-259"></span></p>
<h3>ایندکس‌ها</h3>
<p>وقتی روی یک یا چند ستون ایندکس بذارید mysql یک فهرست از رکوردها که بر اساس اون یک یا چند ستون مرتب شده باشند تهیه و ذخیره میکنه که بعد از این فهرست میتونه برای جستجو و مرتب سازی سریع رکورد ها استفاده کنه.</p>
<p>استفاده از ایندکس ها برای دیتابیس های حجیم اجتناب ناپذیره. ولی یادتون باشه در استفاده از ایندکس ها  زیاده روی نکنید. ایندکس ها سرعت نوشتن و آپدیت کردن رو کند میکنند و حجم جداول رو هم افزایش میدن.<br />
برای اینکه ببینید کجا لازمه از ایندکس استفاده کنید میتونید از تنظیم log-slow-queries استفاده کنید تا کوئری هایی که زمان اجراشون بیش از مقداری که در تنظیم long_query_time تعریف شده باشه لاگ بشه. از تنظیم log-queries-not-using-indexes هم میتونید استفاده کنید تا  کوئری هایی که از ایندکس استفاده نمیکنند رو پیدا کنید (<a title="The Slow Query Log" href="http://dev.mysql.com/doc/refman/5.1/en/slow-query-log.html" target="_blank">توضیحات بیشتر</a>). بعد میتونید با استفاده از <a href="http://dev.mysql.com/doc/refman/5.1/en/using-explain.html" target="_blank">EXPLAIN</a> کوئری‌های مربوطه رو بررسی کنید و در صورت لزوم روی فیلدهایی که لازمه ایندکس بذارید.<br />
البته همه کندی ها مربوط به ایندکس نداشتن نیست گاهی اوقات هم میشه با تغییر در برنامه و بازنگری در کوئری ها بدون افزودن ایندکس  مشکلات رو رفع کرد.</p>
<h3>MyISAM یا InnoDB</h3>
<p>MyISAM و InnoDB دو تا engine معروف mysql هستند. با اینکه MyISAM سرعت بیشتر و حجم کمتری داره ولی معمولا برای  دیتابیس های حجیم از InnoDB استفاده میشه. این کار سه تا علت عمده داره:</p>
<ul>
<li>InnoDB  در عملیات نوشتن از row-level lock استفاده میکنه ولی MyISAM از table-level lock استفاده میکنه.<br />
به عبارت دیگه InnoDB وقتی میخواد یک رکورد بنویسه یا آپدیت کنه فقط همون یک رکورد رو قفل میکنه ولی MyISAM کل جدول رو قفل میکنه. این تفاوت باعث میشه زمانی که تعداد عملیاتهای نوشتن و آپدیت زیاده سرعت InnoDB بیشتر باشه. به عبارتی این عملیات ها در InnoDB میتونن همزمان اجرا بشن ولی در MyISAM هر عملیات باید منتظر اتمام عملیات قبلی بمونه.</li>
<li>جداول InnoDB در هنگام کرش کردن احتیاجی به repair ندارند ولی جداول MyISAM در صورت کرش کردن باید repair بشن.<br />
عملیات repair عملیات فوق العاده زمان بری هست. برای همین استفاده از MyISAM برای جداول حجیم مناسب نیست. من یک جدول MyISAM با حدود 60 میلیون رکورد رو خواستم repair کنم که بعد از گذشت دو روز و تموم نشدن عملیات مجبور شدم kill کنمش و چاره‌ای دیگه بیاندیشم.</li>
<li>از جداول InnoDB میشه در حالیکه دیتابیس فعاله Hot Backup تهیه کرد(با استفاده از <a href="http://www.percona.com/software/percona-xtrabackup/" target="_blank">XtraBackup</a>) ولی برای تهیه Hot Backup از جداول MyISAM باید جداول Lock بشن که باعث میشه در زمان تهیه بکاپ readonly باشند (مگر اینکه از LVM یا replication برای بکاپ گیری استفاده کنیم).</li>
</ul>
<p>InnoDB و MyISAM تفاوت‌های دیگه ای هم دارند مثلا اینکه InnoDB از Transaction و Foreign Key پشتیبانی میکنه ولی MyISAM پشتیبانی نمی‌کنه. همینطور MyISAM از Full-text index پشتیبانی میکنه ولی InnoDB پشتیبانی نمی‌کنه.</p>
<p>یکسری نکات دیگه در مورد InnoDB هست که کمتر توی اینترنت در موردش صحبت شده که عدم آگاهی از اونها میتونه دردسر ساز بشه.</p>
<p>مثلا اینکه با حذف رکورد از جداول InnoDB حجم جداول کاهش پیدا نمیکنه و فضای مربوط به رکوردهای حذف شده آزاد نمیشه. البته این فضا بعدا برای رکوردهای جدید مصرف خواهد شد.<br />
ضمنا InnoDB در حالت پیشفرض داده‌های همه جداول InnoDB مربوط به همه دیتابیس ها رو در یک فایل مشترک(ibdata1) ذخیره می‌کنه در این حالت حتی با حذف جدول هم فضای مصرفی اون جدول آزاد نمیشه. برای همین اگر قصد استفاده از InnoDB رو دارید حتما تنظیم innodb_file_per_table رو در فایل my.cnf قرار بدید تا داده‌های هر جدول در شاخه‌ی دیتابیس مربوطه و با نام متناظر با جدول ذخیره بشه. البته یادتون باشه که حتی در صورت استفاده از این گزینه باز هم جداول InnoDB مستقل نیستند و وابسته به فایلهای ibdata1 و ib_logfile ها هستند. به عبارتی با کپی گرفتن از شاخه یک دیتابیس و منتقل کردنش به یک سرور دیگه نمیشه جداول InnoDB رو منتقل کرد و همچنین برای تهیه پشتیبان کپی کردن شاخه دیتابیس تنها کافی نیست. در حالی که اینکارها برای جداول MyISAM براحتی امکان پذیره.<br />
البته برای انتقال یک جدول InnoDB بین دو دیتابیس روی یک سرور می‌تونید از RENAME TABLE استفاده کنید.</p>
<p>InnoDB بر خلاف MyISAM تعداد رکوردها رو ذخیره نمی‌کنه. که باعث میشه COUNT گرفتن بدون استفاده از WHERE روی جداول InnoDB خیلی زمان‌بر باشه و برای جداول حجیم عملا غیر ممکن باشه. در واقع نیاز به استفاده از COUNT بدون WHERE به ندرت پیش میاد که احتمالا قابل صرف نظر کردن هست. البته اگر رکوردی از جدول حذف نمی‌کنید می‌تونید به جای COUNT از MAX(id)‎ استفاده کنید. یک راه دیگه استفاده از Trigger هست که توصیه نمیشه چون performance رو پایین میاره.</p>
<p>در ضمن برای استفاده بهینه از InnoDB در صورتی که از سرور اختصاصی برای mysql استفاده می‌کنید می‌تونید مقدار innodb_buffer_pool_size را حدود 70-80 درصد از حافظه RAM قرار بدین. (<a title="Choosing innodb_buffer_pool_size" href="http://www.mysqlperformanceblog.com/2007/11/03/choosing-innodb_buffer_pool_size/" target="_blank">توضیحات بیشتر</a>)</p>
<h3>ALTER</h3>
<p>زمانی که بخواهید تغییری در ستون های جداول ایجاد کنید یا ایندکس حذف یا اضافه کنید و یا engine جدول رو تغییر بدید روش معمول استفاده از دستور ALTER هست که خیلی  زمانبر هست. یک جایگزین سریعتر برای Alter اینه که یک جدول خالی با تغییراتی که مد نظرتون هست بسازید و بعد با استفاده از INSERT INTO new_table SELECT * FROM old_table  اطلاعات رو به جدول جدید منتقل کنید. و یا در صورت کمبود حافظه ابتدا با استفاده از SELECT INTO OUTFILE خروجی تهیه کنید و سپس با LOAD DATA INFILE اطلاعات رو به جدول جدید منتقل کنید. این روش حدود 50 درصد از ALTER سریعتر هست. (<a title="What's faster than ALTER?" href="http://everythingmysql.ning.com/profiles/blogs/whats-faster-than-alter" target="_blank">توضیحات بیشتر</a>)</p>
<p>تغییر در جداول حتی با استفاده از روشهای فوق هم عملیات زمانبری است و اگر بخواهید بدون Downtime روی جداول حجیم تغییرات ایجاد کنید تنها راه استفاده از Replication است که در ادامه مطلب در موردش توضیح میدم.</p>
<h3>Replication</h3>
<p>برای اینکه میرور لحظه‌ای از دیتابیس خود داشته باشید باید از replication استفاده کنید.<br />
در replication ما یک سرور master داریم که با استفاده از قابلیتی به نام Binary log همه عملیات هایی که منجر به تغییرمیشه نظیر Insert و Update وDelete  و Alter و &#8230; رو لاگ میکنه. بعدا سرور یا سرورهای slave که حاوی میروری از دیتابیس های سرور master هستند از این binlog ها برای اعمال همان تغییرات روی میرورها و بروز نگهداشتن میرورها استفاده میکنند. در این حالت باید همه‌ی عملیات هایی که منجر به تغییر میشن فقط روی سرور master اجرا بشن و از سرورهای slave فقط برای خوندن استفاده بشه. در غیر اینصورت میرورها از سینک خارج میشن.</p>
<p>استفاده از replication و binary log کاربردهای زیادی داره از جمله:</p>
<ul>
<li><strong>Load Balancing<br />
</strong>وقتی یک سرور جوابگوی پاسخ به همه حجم ترافیک نباشه باید از چند تا سرور استفاده کرد. خوب در مرحله اول میشه وبسرور و سرور mysql رو جدا کرد. اما وقتی یک سرور اختصاصی برای mysql هم جوابگو نبود باید از replication استفاده کرد تا بار پردازشی بین چند تا سرور توزیع بشه. با توجه به اینکه معمولا حجم عملیات نوشتن کمتر از حجم خواندن از دیتابیس هست میشه برنامه رو طوری طراحی کرد که از سرور master فقط برای نوشتن استفاده کنه و از سرورهای slave برای خوندن.</li>
<li><strong>Failover<br />
</strong>تصور کنید دیتابیس حجیمتون به خاطر یک اشکال سخت افزاری یا نرم افزاری از کار بیافته طوریکه مجبور باشید دیتابیس رو از روی بکاپ ها بازیابی کنید. این کار بسته به حجم دیتابیس ممکنه ساعتها طول بکشه و در مورد یک سرویس اینترنتی ممکنه ثانیه ها هم ارزش داشته باشند. اینجاست که از replication برای failover استفاده میشه. به این صورت که به محض مشکل دار شدن سرور master یکی از سرورهای slave تبدیل به master میشه. و از اون لحظه به بعد همه عملیات های نوشتن اون رو انجام میشه و سایر slave ها هم خودشون رو از اون رو بروز میکنند. بعد از رفع مشکل سرور master قدیمی به عنوان یک سرور slave وارد مدار میشه.<br />
<img class="aligncenter size-full wp-image-274" title="failover" src="http://farhadi.ir/blog/wp-content/uploads/2010/10/failover.png" alt="failover" width="450" height="600" /></li>
<li><strong>Backup<br />
</strong>بعضی ها replication رو با بکاپ اشتباه می‌گیرند. برای روشن شدن موضوع یک مثال میزنم. فرض کنید روی سرور اصلی یک نفر اشتباها یک کوئری drop اجرا کنه و یک جدول مهم رو پاک کنه. در این صورت این کوئری روی سرورهای slave هم اجرا میشه و دیگه نمیشه از slave ها به عنوان پشتیبان استفاده کرد و اطلاعات رو برگردوند. بنابراین replication به تنهایی راه حلی برای بکاپ گیری نیست.<br />
اما ببینیم چطور میشه از replication برای بکاپ گیری استفاده کرد.<br />
در روش اول میشه از binary log به تنهایی (بدون استفاده از replication) برای تهیه بکاپ افزایشی (Incremental) استفاده کرد. به این صورت که یکبار از کل دیتابیس پشتیبان تهیه می‌کنید بعد از اون هر روز binary log های اون روز رو روی پشتیبان اجرا می‌کنید تا همیشه یک پشتیبان بروز داشته باشید بدون اینکه نیاز باشه هر روز از کل دیتابیس پشتیبان تهیه کنید. و در صورت بروز مشکل میتونید از روی binary log ها پشتیبان خود را تا لحظه قبل از وقوع مشکل بروز کنید. (کل این عملیات با استفاده از ابزار <a href="http://www.percona.com/software/percona-xtrabackup/" target="_blank">XtraBackup</a> به راحتی قابل انجامه).<br />
روش دوم اینه که از یک سرور slave استفاده کنیم تا هیچ downtime و بار پردازشی روی سرور اصلی ایجاد نشه. در این حالت با خیال راحت میتونیم سرور slave رو stop کنیم و از دیتابیس بکاپ تهیه کنیم و مجددا سرور رو استارت کنیم. بعد از استارت شدن سرور مجددا شروع به بروز شدن از همان لحظه توقف میکند.</li>
<li><strong>ALTER بدون downtime<br />
</strong>یکی دیگه از کاربردهای replication تغییر در ساختار جداول بزرگ هست. همون طور که قبلا گفتم Alter دستور زمان بری هست. طوری که ممکنه برای یک جدول حجیم یک تغییر نظیر افزودن ایندکس روی یک فیلد یا اضافه کردن یک ستون جدید به جدول ساعت ها یا حتی روزها طول بکشه. توی این حالت برای اینکه downtime نداشته باشیم میتونیم از یک سرور slave استفاده کنیم به این صورت که ابتدا روی سرور slave دستور STOP SLAVE رو اجرا میکنیم تا عملیات بروز شدن از master متوقف بشه. بعد تغییرات رو روی جداول مورد نظر می‌دیم. بعد از اتمام تغییرات دستور START SLAVE رو اجرا میکنیم تا مجددا سرور ما از سرور اصلی بروز بشه. بعد از اینکه مطمئن شدیم سرور slave ما با سرور اصلی sync هست جای سرور slave و master رو عوض می‌کنیم. حالا میتونیم سرور master قدیمی(که الان slave هست) رو هم تغییرات رو روش اعمال کنیم و به عنوان slave ازش استفاده کنیم.</li>
<li><strong>کاربردهای خاص</strong><br />
از replication برای کاربردهای خاص دیگه ای هم میشه استفاده کرد. مثلا فرض کنید ما به Full-text search روی یکی از فیلدهای یک جدول InnoDB احتیاج داشته باشیم. و نخواهیم به دلایلی که گفته شد از MyISAM استفاده کنیم. در این حالت میتونیم از replication استفاده کنیم. به این صورت که جدول ما روی سرور اصلی InnoDB هست ولی روی یکی از سرورهای slave که مخصوص full-text search ایجاد کردیم همان جدول را از نوع MyISAM داریم. حالا برنامه رو طوری طراحی میکنیم که برای کوئری هایی که احتیاج به full-text search هست از این slave استفاده کنه.</li>
</ul>
<h3>حرف آخر</h3>
<p>در نهایت یادتون باشه خودتون رو محدود به mysql نکنید شاید اصلا mysql گزینه مناسبی برای کار شما نباشه. این روزها تب دیتابیس های <a href="http://en.wikipedia.org/wiki/NoSQL" target="_blank">NoSQL</a> هم داغ هست یک سری به اونها هم بزنید. برای نمونه <a href="http://www.mongodb.org/" target="_blank">mongodb</a> دیتابیس فوق العاده ای برای کارهای بزرگ هست. بنچمارک ها نشون میده سرعتش از mysql خیلی بیشتره و قابلیت های فوق‌العاده ای نظیر Map-Reduce و پشتیبانی خیلی خوب از Replication و Sharding داره. اگر فرصت کنم در یک مطلب جداگانه در موردش مفصل توضیح میدم.</p>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1389/08/13/dealing-with-large-mysql-databases/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>WebExtract</title>
		<link>http://farhadi.ir/blog/1389/07/21/webextract/</link>
		<comments>http://farhadi.ir/blog/1389/07/21/webextract/#comments</comments>
		<pubDate>Tue, 12 Oct 2010 23:02:32 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[متفرقه]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=248</guid>
		<description><![CDATA[بعد از تحریم cpanel و جایگزینی اون با plesk یکی از گلایه های مشتری ها عدم امکان باز کردن فایلهای فشرده از طریق کنترل پنل بوده.
از اونجایی که این امکان، امکان پرطرفداری بود. تصمیم گرفتم که برنامه ای برای این کار بنویسم تا کور بشه چشم هر کی که بخواد ما رو تحریم کنه  [...]]]></description>
			<content:encoded><![CDATA[<p>بعد از تحریم cpanel و جایگزینی اون با plesk یکی از گلایه های مشتری ها عدم امکان باز کردن فایلهای فشرده از طریق کنترل پنل بوده.</p>
<p>از اونجایی که این امکان، امکان پرطرفداری بود. تصمیم گرفتم که برنامه ای برای این کار بنویسم تا کور بشه چشم هر کی که بخواد ما رو تحریم کنه <img src='http://farhadi.ir/blog/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>این شد که دست به کار شدم و <a href="http://github.com/farhadi/webextract" target="_blank">WebExtract</a> رو با پایتون نوشتم. این برنامه یک Daemon هست که به صورت یک سرویس نصب میشه و روی پورت 2121 سرویس میده و از یوزر و پسورد های سیستم برای احراز هویت استفاده میکنه. به عبارتی بعد از نصب این برنامه کاربر با رفتن به آدرس سایت خودش روی پورت 2121 می‌تونه با وارد کردن نام کاربری و رمز ftp ، فایلها و فولدرهای خودش رو ببینه و فایل های فشرده رو آنلاین باز کنه.</p>
<p>در ادامه نحوه نصبش رو توضیح میدم.</p>
<p><span id="more-248"></span></p>
<p>قبل از هر چیز این نکته رو بگم که برای نصب این برنامه باید دسترسی root به سرور داشته باشید. به عبارتی اگر میخواین این امکان رو روی هاستتون داشته باشید باید با مدیر سرورتون تماس بگیرید و ازش بخواهید که این برنامه رو براتون روی سرور نصب کنه. (که البته اگر نصب نکرد کاری از من ساخته نیست و اگر هم نصب کرد مسئولیتش با خودشه!)</p>
<p><strong>اما نحوه نصب:</strong></p>
<p>برای اجرای این برنامه باید پایتون 2.5 به بالا داشته باشید که اگر ندارید میتونید از سایتش دریافت، کامپایل و نصب کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">wget http://www.python.org/ftp/python/2.7/Python-2.7.tgz
tar xvfz Python-2.7.tgz
cd Python-2.7
./configure
make
make install</pre></div></div>

<p>بسته‌ی webextract رو هم از <a href="http://github.com/downloads/farhadi/webextract/webextract-1.0.tar.gz">اینجا</a> دریافت و نصب ‌کنید:</p>

<div class="wp_syntax"><div class="code"><pre class="text text" style="font-family:monospace;">wget http://github.com/downloads/farhadi/webextract/webextract-1.0.tar.gz
tar xvfz webextract-1.0.tar.gz
cd webextract-1.0
make install</pre></div></div>

<p>برنامه آمادست. در ضمن پورت 2121 هم باید روی فایروال سرور باز باشه.</p>
<p>اگر موقع باز کردن فایلهای فشرده با خطای «sorry, you must have a tty to run sudo» مواجه شدید باید دستور visudo رو اجرا کنید و دنبال خط «Default requiretty» بگردید و کامنتش کنید و ذخیرش کنید. (دیگه vi باید بلد باشید.)</p>
<p>در صورت لزوم پورت برنامه رو هم می‌تونید در فایل ‎/etc/webextract.conf تغییر بدید. البته یادتون باشه بعد از تغییر، برنامه رو restart کنید. (‎/etc/init.d/webextract restart)</p>
<p>من این برنامه رو روی debian ، ubuntu و CentOS تستش کردم ولی باید روی همه‌ی توزیع های بر پایه دبیان و ردهت کار کنه.</p>
<p>اگر به مشکلی برخوردید <a href="http://github.com/farhadi/webextract/issues" target="_blank">اینجا</a> گزارش بدید.</p>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1389/07/21/webextract/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>مظلومیت اینترنت</title>
		<link>http://farhadi.ir/blog/1389/06/10/internet-oppression/</link>
		<comments>http://farhadi.ir/blog/1389/06/10/internet-oppression/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 19:51:21 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[متفرقه]]></category>
		<category><![CDATA[وب]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=228</guid>
		<description><![CDATA[اینترنت در ایران واقعا مظلومه.
اینجا اینترنت به عنوان یک ابزار تفننی شناخته میشه و گاهی اوقات هم به عنوان یک معضل. و متاسفانه به نظر میرسه که هر روز این وضع داره بدتر میشه. یک دوستی می‌گفت وظیفه ماست که در این مورد اطلاع رسانی کنیم تا بلکه صدامون به گوش کسی برسه که دستش [...]]]></description>
			<content:encoded><![CDATA[<p>اینترنت در ایران واقعا مظلومه.</p>
<p>اینجا اینترنت به عنوان یک ابزار تفننی شناخته میشه و گاهی اوقات هم به عنوان یک معضل. و متاسفانه به نظر میرسه که هر روز این وضع داره بدتر میشه. یک دوستی می‌گفت وظیفه ماست که در این مورد اطلاع رسانی کنیم تا بلکه صدامون به گوش کسی برسه که دستش به جایی میرسه &#8230;</p>
<p><span id="more-228"></span>اینجا به مناسبت های مختلف نظیر 22 بهمن و روز قدس و سالگرد انتخابات و &#8230; اینترنت دچار اختلال میشه. طوری که تقریبا از اینترنت جز پروتکل http چیز دیگه ای باقی نمی‌مونه. و هیچ نهاد و ارگان و سازمانی هم مسئولیت این اختلالات رو به عهده نمی‌گیره.<br />
شاید برای کاربران عادی عمق این فاجعه مشخص نباشه ولی این اختلالات میتونه خسارات جبران ناپذیری برای شرکت ها و صنایع وابسته به اینترنت داشته باشه. مثلا پرداخت های اینترنتی رو در نظر بگیرید که به خاطر قطعی https می‌تونه باعث لغو یک قرارداد یا آزاد شدن یک دامنه و یا خیلی مشکلات دیگه بشه. برای نمونه ما برای پرداخت هزینه یک سرور اختصاصی برای یک مشتری به خاطر اختلال بوجود آمده دچار مشکل شدیم. از یک طرف باعث بد قولی و بی اعتبار شدن ما پیش مشتری میشه از طرفی هر روز تاخیر در راه اندازی سرور کلی خسارت به مشتری وارد میکنه و در نهایت تاخیر در پرداخت باعث اضافه شدن جریمه تاخیر به قرارداد و بد حساب شدن ما میشه. یا یک نمونه دیگه عدم دسترسی مشتری های هاستینگ به پنل مدیریت هاستشون به خاطر اختلال https هست. که باعث نارضایتی مشتری‌ها میشه. از طرفی اختلال در دسترسی SSH به سرورها هم مشکلات عدیده ای رو برامون بوجود میاره.<br />
یک نمونه دیگه هم بسته شدن دسترسی به فایل های فلش خارج از کشور بود که باعث شده بود یکسری گزارشات و امکاناتی که با استفاده از فلش تولید شده بود از کار بیافتند. این مورد هم علاوه بر اینکه کلی از مشتری ها رو شاکی کرده بود کلی وقت هم از تیم فنی گرفته شد تا پی به علت اشکال ببرند.<br />
آخرین نمونه هم امروز بود که به خاطر اشکال دسترسی https امکان تمدید و ثبت دامنه IR وجود نداره و معلوم هم نیست کی درست بشه. خوشبینانه ترین حالت اینه که 48 ساعت این قطعی ادامه داشته باشه و همین قدر کافیه تا کلی خسارت به مالکان دامنه های درحال انقضا وارد بشه. خلاصه از این دست مشکلات و خسارات بسیارند و هیچ کس مسؤلیت این خسارات رو بعهده نمی‌گیره.</p>
<p>مشکل دیگه ای که اینترنت ایران باهاش مواجه هست قطعی‌ها و کندی‌های مکرر به خاطر پاره شدن کابل و یا اختلالات زیرساختی هست. در این مورد از لحاظ فنی من اظهار نظر نمیکنم ولی مسلما باید راهی وجود داشته باشه که با پاره شدن یک کابل کل اینترنت یک منطقه از کشور برای چند روز دچار قطعی و اختلال نشه. البته شایعاتی هم هست که قطعی کابل بهانه هست و اختلالات دلایل سیاسی داره. هر چی که هست تا وقتی این مشکلات هست پیشرفتی هم توی این صنعت دیده نخواهد شد. نمیشه انتظار داشت که بخش خصوصی به این بازار بی ثبات اطمینان کنه و مثلا بیاد اینجا دیتاسنتر راه اندازی کنه در حالی که میشه با هزینه خیلی کمتر و کیفیت خیلی بیشتر این خدمات رو از خارج تهیه کرد.</p>
<p>مشکل دیگه ای که کاربران اینترنت ایران ازش رنج می‌برند محدودیت 128 کیلوبیتی سرعت دسترسی برای کاربران خانگی هست.<br />
این طرز تفکر که این سرعت برای مصارف خانگی کافیه از اونجا ناشی میشه که مسئولین مربوطه تصور میکنند تنها کاربرد اینترنت چت کردن و دوستیابی و در نهایت بازدید از چند صفحه وب هست و خلاصه اینکه تصور میکنند اینترنت یک ابزار تفننی است.<br />
الان دنیا به جایی رسیده که از سیستم عامل های تحت وب و سرویسهای ابری (cloud) و اپلیکشن‌های تحت وب استفاده میشه در حالی که ما حتی درک درستی هم از این مفاهیم نداریم. البته اگر اکثریت مردم ما جز چت و دوستیابی استفاده‌ی مفید دیگری از اینترنت نمی‌کنند به این خاطر است که با این سرعت کاری غیر از این هم نمی‌شود کرد. در واقع ما با اعمال این محدودیت مانع از ظهور و رشد کاربردهای مفید اینترنت می‌شیم.</p>
<p>مشکل بعدی اینه که هر روز شاهد مسدود شدن دسترسی به سایت‌ها و سرویس‌های مختلف هستیم. گرچه وجود فیل+ترینگ لازمه ولی نباید سایت ها و سرویس های مفید رو به خاطر اثرات مخربی که ممکنه داشته باشند مسدود کرد. از جمله این موارد سرویس های اجتماعی و کلا سایت‌های وب دویی هستند که محتواشون توسط کاربرهاشون تامین میشه. مشکل نظام با سرویس های وب دویی از اونجایی ناشی میشه که اکثریت حاکم بر جامعه با اکثریت حاکم بر شبکه های اجتماعی صد و هشتاد درجه اختلاف داره. ما در واقع با مسدود کردن این سرویس ها کلا صورت مسئله رو پاک می‌کنیم. راه حل این مشکل بالا بردن ضریب نفوذ اینترنت و فرهنگ سازی برای دسترسی عموم مردم به اینترنت و در نتیجه کم کردن فاصله بین جامعه مجازی با جامعه حقیقی هست.</p>
<p>تحریم های روز افزون از طرف شرکت ها و سرویس های خارجی هم که قوض بالا قوض شده.<br />
در این مورد به نظر من همون طور که نظام برای مسدود کردن سایت های مخرب سرمایه گذاری میکنه باید برای فراهم کردن امکان دسترسی به سایت های مفیدی که از اون طرف مسدود شده هم سرمایه گذاری کنه.</p>
<p>معضل آخر هم سیاست های غلط دولت و سازمان های ذیربط در مورد اینترنت هست. سیاست‌ها و تصمیمات غلطی که بعضا بیشتر به طنز شبیه هست. مواردی نظیر طرح ساماندهی، اینترنت ملی، ایمیل ملی، موتور جستجوی ملی، دیتاسنتر ملی و &#8230; . قطعا داشتن سرویس های بومی اینترنت خیلی خوبه و حتی ضروریه. کافیه گوگل دسترسی کاربران ایرانی رو مسدود کنه تا اهمیت موضوع روشن بشه. پس در اینکه رسیدن به این اهداف باید جزو برنامه ‌های اصلی دولت باشه شکی نیست. اما این اهداف اهدافی نیستند که یک شبه محقق بشوند. با یارانه و وام و &#8230; هم نمیشه با غول های اینترنتی مثل گوگل و یاهو رقابت کرد.<br />
وظیفه دولت فراهم کردن زیر ساخت ها و بستر سازی و حمایت از بخش خصوصی برای سرمایه گذاری در اینترنت هست. قطعا اگر زیرساخت‌ها اصلاح بشه و اینترنت بستر امنی برای سرمایه گذاری باشه و قوانین دست و پاگیر و هزینه های سرسام آور برای شرکت‌های خصوصی نداشته باشه میتونیم در عرض 5 سال سرویس های بومی و در عرض 10 سال سرویس های بین المللی قابل رقابت با دنیا داشته باشیم.</p>
<p>خلاصه اینکه اگر اینترنت جایگاه واقعی خودش رو پیدا کنه میتونه باعث ایجاد شغل به صورت مستقیم و غیر مستقیم برای چند ده هزار نفر بشه، میتونه ارز آوری های کلان داشته باشه، میتونه سطح آگاهی‌ و دانش عمومی جامعه رو بالا ببره، میتونه باعث افزایش کیفیت زندگی، کاهش ترافیک و کاهش هزینه‌های اضافی و تسهیل در ارائه خدمات مختلف بشه و از همه مهمتر اینکه میتونه تاثیر مستقیم و چشمگیر در افزایش سرعت رشد علمی کشور داشته باشه.</p>
<p>به هر حال امیدوارم روزی برسه که مسئولان به اهمیت این موضوع پی ببرند و ما شاهد اینترنتی در شأن مردم ایران باشیم.</p>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1389/06/10/internet-oppression/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>تقویم فارسی (هجری شمسی) برای N900</title>
		<link>http://farhadi.ir/blog/1389/02/15/persian-calendar-for-n900/</link>
		<comments>http://farhadi.ir/blog/1389/02/15/persian-calendar-for-n900/#comments</comments>
		<pubDate>Tue, 04 May 2010 23:12:20 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[لینوکس]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[maemo]]></category>
		<category><![CDATA[n900]]></category>
		<category><![CDATA[persian]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=218</guid>
		<description><![CDATA[تقریبا یک ماهی میشه که n900 خریدم.
به قول امیر محمد سعید ما ایرانی ها هر وقت یک پلتفرم جدید به دستمون میرسه اولین کاری که میکنیم یک تقویم فارسی براش مینویسیم. شاید یک علتش اینه که بقیه چیزها رو بقیه نوشتن و پیدا کردن ایده جدید کار سختیه.
به هر حال من هم از همون روزهای [...]]]></description>
			<content:encoded><![CDATA[<p>تقریبا یک ماهی میشه که n900 خریدم.</p>
<p>به قول <a href="http://mybabblebox.blogspot.com/2009/05/widget-android.html" target="_blank">امیر محمد سعید</a> ما ایرانی ها هر وقت یک پلتفرم جدید به دستمون میرسه اولین کاری که میکنیم یک تقویم فارسی براش مینویسیم. شاید یک علتش اینه که بقیه چیزها رو بقیه نوشتن و پیدا کردن ایده جدید کار سختیه.</p>
<p>به هر حال من هم از همون روزهای اول به فکر نوشتن یک تقویم شمسی برای این گوشی بودم. تا اینکه یک روز به ذهنم زد که از <a href="http://icu-project.org/ " target="_blank">کتابخونه icu</a> استفاده کنم اینطوری میشد یک تقویمی نوشت که همه تقویم ها و زبانهای دنیا رو ساپورت کنه. گفتم حتما پایتون ماژول برای icu داره توی پکیج های پایتون گشتم دیدم بعله pyicu هست. فقط یک مشکلی بود که تو پکیج های pymaemo نبود. خلاصه سورسش رو گرفتم بردم تو SDK برای armel کامپایل کردم. فایل ها رو ریختم رو گوشی و یک اسکریپت کوچولوی پایتون برای تستش نوشتم. مثل باقلوا کار کرد. دست به کار شدم یک ویجت براش نوشتم. یک تایمر هم گذاشتم راس ساعت ۱۲ شب ویجت رو رفرش کنه. در ضمن با استفاده از dbus-monitor سیگنال تغییر زمان سیستم رو هم پیدا کردم تا بتونم در صورت تغییر دستی تاریخ ویجت رو رفرش کنم.</p>
<p>ویجت رو قابل تکثیر تعریف کردم تا بشه تقویم های مختلف رو همزمان داشت و از gconf برای ذخیره تنظیمات استفاده کردم.</p>
<p>خلاصه نتیجه شد این:</p>
<p><a href="http://farhadi.ir/blog/wp-content/uploads/2010/05/screenshot00.png"><img class="alignnone size-medium wp-image-219" title="n900-persian-calendar" src="http://farhadi.ir/blog/wp-content/uploads/2010/05/screenshot00-300x180.png" alt="n900-persian-calendar" width="300" height="180" /></a></p>
<p>پکیجش کردم گذاشتمش تو مخزن extras-devel :</p>
<p><a href="http://maemo.org/packages/view/multical-date-widget/" target="_blank">http://maemo.org/packages/view/multical-date-widget/</a></p>
<p><strong>آپدیت:</strong><br />
برای نصب این برنامه لینک زیر رو روی گوشی باز کنید:</p>
<p><a href="http://farhadi.ir/downloads/multical-date-widget.install">http://farhadi.ir/downloads/multical-date-widget.install</a></p>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1389/02/15/persian-calendar-for-n900/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>تقویم فارسی برای php 5.3</title>
		<link>http://farhadi.ir/blog/1389/02/10/persian-calendar-for-php-53/</link>
		<comments>http://farhadi.ir/blog/1389/02/10/persian-calendar-for-php-53/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 20:30:03 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=211</guid>
		<description><![CDATA[شش ماه پیش امید متقی توی وبلاگش در مورد پشتیبانی php 5.3 از تقویم فارسی نوشته بود. این امکان با اضافه شدن اکستنشن Intl به اکستنشن های پیشفرض php در نسخه 5.3 به بعد فراهم شده. این اکستنشن در واقع امکان کار با کتابخونه ICU رو برای php فراهم میکنه.  دیدم کار با این توابع [...]]]></description>
			<content:encoded><![CDATA[<p>شش ماه پیش <a href="http://oxygenws.com/blog" target="_blank">امید متقی</a> توی وبلاگش در مورد <a href="http://oxygenws.com/blog/archives/72-..-..html" target="_blank">پشتیبانی php 5.3 از تقویم فارسی</a> نوشته بود. این امکان با اضافه شدن <a href="http://pecl.php.net/package/intl" target="_blank">اکستنشن Intl</a> به اکستنشن های پیشفرض php در نسخه 5.3 به بعد فراهم شده. این اکستنشن در واقع امکان کار با کتابخونه <a href="http://www.icu-project.org/" target="_blank">ICU</a> رو برای php فراهم میکنه.  دیدم کار با این توابع یک کمی مشکله تصمیم گرفتم با این توابع یک توسعه برای کلاس DateTime بنویسم که کار باهاش آسون بشه. این شد که چهار ماه پیش این کلاس رو نوشتم (<a href="http://github.com/farhadi/IntlDateTime">اینجا</a>) ولی خوب به خاطر مشغله کاری و تنبلی وقت نکردم در موردش چیزی بنویسیم.</p>
<p>با این کلاس در واقع همون امکانات DateTime رو به اضافه پشتیبانی از تقویم‌ها و زبان‌های مختلف دارید. برای مثال:</p>

<div class="wp_syntax"><div class="code"><pre class="php php" style="font-family:monospace;"><span style="color: #000088;">$date</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> IntlDateTime<span style="color: #009900;">&#40;</span><span style="">'now'</span><span style="color: #339933;">,</span> <span style="">'Asia/Tehran'</span><span style="color: #339933;">,</span> <span style="">'persian'</span><span style="color: #339933;">,</span> <span style="">'fa'</span><span style="color: #009900;">&#41;</span>;
<span style="color: #990000;">echo</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">format</span><span style="color: #009900;">&#40;</span><span style="">'yyyy/MM/dd'</span><span style="color: #009900;">&#41;</span>; <span style="color: #666666; font-style: italic;">// ۱۳۸۹/۰۲/۱۰</span>
<span style="color: #990000;">echo</span> <span style="color: #000088;">$date</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">format</span><span style="color: #009900;">&#40;</span><span style="">'E dd LLL yyyy'</span><span style="color: #009900;">&#41;</span>; <span style="color: #666666; font-style: italic;">// جمعه ۱۰ اردیبهشت ۱۳۸۹</span></pre></div></div>

<p>نحوه کارش مشابه کلاس DateTime هست با تفاوت های زیر:</p>
<ol>
<li>پارامتر اول علاوه بر رشته میتونه timestamp و یا یک شی از نوع DateTime باشه.</li>
<li>در پارامتر اول کاراکترهای عددی به هر زبانی میتوانند باشند. یعنی اگر رشته شما شامل اعداد فارسی یا عربی یا ترکیبی از اونها و یا هر زبون دیگه ای که باشه با این کلاس بدون مشکل کار میکنه. (این قسمت رو به لطف کلاس NumberFormatter که یکی دیگه از امکانات intl هست نوشتم )</li>
<li>برای پارامتر دوم به جای شی DateTimeZone میشه از رشته هم استفاده کرد.</li>
<li>پارامتر سوم نوع تقویم رو مشخص میکنه که میتونه Buddhist, Chinese, Coptic, Ethiopic, Gregorian, Hebrew, Indian, Islamic, Islamic-Civil, Japanese, Persian, Taiwan باشه. (دم ICU گرم فکر کنم فقط تقویم مایاها رو یادشون رفته پیاده کنن!)</li>
<li>پارامتر چهارم زبانه برای مثال میتونه fa ، fa_IR ، en ، en_US ، en_UK و &#8230; باشه</li>
<li>یکی از سختی های کار با کلاس IntlDateFormatter اینه که باید حتما pattern تاریخ رو مشخص کنید ولی کلاس IntlDateTime در اکثر مواقع خودش میتونه pattern رو تشخیص بده و برای موارد خاص که pattern توسط کلاس قابل تشخیص نباشه باید خودتون pattern رو به عنوان پارامتر پنجم بدید.</li>
<li>برای استفاده از متد format باید pattern رو به <a href="http://userguide.icu-project.org/formatparse/datetime" target="_blank">فرمتی که ICU قبول میکنه</a> بدید. برای استفاده از فرمت خود php  از متد classicFormat استفاده کنید.</li>
<li>متد فرمت timezone هم به عنوان پارامتر دوم قبول میکنه (بدون تغییر timezone داخلی شی)</li>
<li>کلاس IntlDateFormatter با تایم زون هایی که DST دارن مشکل داره که من توی IntlDateTime رفعش کردم.</li>
<li><del datetime="2010-09-09T18:22:36+00:00">تنها اشکالش اینه که با تاریخ های خارج از محدوده timestamp کار نمیکنه که به عنوان باگ برای IntlDateFormatter گزارش دادم.</del> (<strong>آپدیت:</strong> این مشکل هم <a href="http://bugs.php.net/bug.php?id=50590" target="_blank">رفع شد</a>.)</li>
<li>متد modify تاریخ رو مطابق با تقویمی که ست شده ویرایش میکنه (مثلا برای تاریخ امروز +1 month رو اگر روی تقویم میلادی اجرا کنی 30 روز و اگر روی تقویم هجری شمسی اجرا کنی 31 روز تاریخ رو جلو میبره)</li>
<li>با متد setCalendar و setLocale تقویم و زبان رو میتونید عوض کنید که مثلا برای تبدیل تاریخ از میلادی به شمسی و بالعکس کاربرد داره.</li>
</ol>
<p>یک تعداد testcase هم براش نوشتم که برای آشنایی با طرز کار کلاس میتونین یک نگاهی بهش بندازین. البته هنوز تستهاش کامل نیست. بعدا اگه فرصت کنم کاملش میکنم.</p>
<p>همونطور که گفتم این کلاس فقط روی php 5.3 به بعد کار میکنه اگر دنبال کدی میگردید که روی php 5 هم کار کنه یک کلاس دیگه نوشتم (<a href="http://github.com/farhadi/ExtDateTime" target="_self">اینجا</a>) که البته محدودیت هایی نسبت به این کلاس داره (در حال حاضر فقط تقویم فارسی و میلادی رو ساپورت میکنه ولی قابل گسترش برای سایر تقویم ها هست. از الگوی factory استفاده میکنه و بعد از ایجاد شی دیگه تقویم قابل تغییر نیست.)</p>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1389/02/10/persian-calendar-for-php-53/feed/</wfw:commentRss>
		<slash:comments>21</slash:comments>
		</item>
		<item>
		<title>فشرده ساز اسکریپت گوگل</title>
		<link>http://farhadi.ir/blog/1388/09/29/google-closure-compiler/</link>
		<comments>http://farhadi.ir/blog/1388/09/29/google-closure-compiler/#comments</comments>
		<pubDate>Sat, 19 Dec 2009 21:22:00 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Compressor]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[Minifier]]></category>
		<category><![CDATA[Yahoo]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=203</guid>
		<description><![CDATA[از زمانی که استفاده از جاوا اسکریپت در اینترنت رونق پیدا کرد، توسعه دهنده ها به این فکر افتادند که ابزارهایی برای فشرده سازی یا بهتر بگیم چلاندن اسکریپت ها بنویسند. منظور از چلاندن(Minification)، خلاصه  و کوتاه کردن اسکریپت بدون تغییر در عملکرد آن است. که این کار با حذف فضاهای خالی، کامنت ها و [...]]]></description>
			<content:encoded><![CDATA[<p>از زمانی که استفاده از جاوا اسکریپت در اینترنت رونق پیدا کرد، توسعه دهنده ها به این فکر افتادند که ابزارهایی برای فشرده سازی یا بهتر بگیم چلاندن اسکریپت ها بنویسند. منظور از چلاندن(Minification)، خلاصه  و کوتاه کردن اسکریپت بدون تغییر در عملکرد آن است. که این کار با حذف فضاهای خالی، کامنت ها و یکسری تکنیک‌های دیگر انجام می‌شود.</p>
<p>اولین ابزارهایی که در این زمینه تولید شدند الگوریتم های ساده ای داشتند که با استفاده از Reqular Expression ها کار می‌کردند و به همین دلیل مشکلاتی هم داشتند. برای مثال <a href="http://www.crockford.com/javascript/jsmin.html" target="_blank">JSMin</a> و <a href="http://dean.edwards.name/packer/" target="_blank">Dean Packer</a> از چلاننده(Minifier) های معروفی هستند که به همین روش کار می‌کنند. مثلا JSMin نمی‌تواند همه‌ی کاراکترهای خط جدید (line feed) را حذف کند چون ممکن است باعث بوجود آمدن باگ در برنامه شود. Dean Packer هم برای اینکه درست کار کند باید تمام دستورات اسکریپت به «;» ختم شده باشند.</p>
<p>این شد که توسعه دهنده ها به فکر تولید چلاننده‌هایی افتادند که بتواند مثل یک موتور اسکریپت (JavaScript Engine) اسکریپت را تفسیر نموده و به بهینه ترین نحو بچلاند. اولین چلاننده از این نسل <a href="http://www.dojotoolkit.org/docs/shrinksafe" target="_blank">Dojo ShrinkSafe</a> بود که بر پایه موتور اسکریپت Rhino نوشته شده است. کمی بعد یاهو هم چلاننده ای تولید کرد با نام <a href="http://yuilibrary.com/projects/yuicompressor" target="_blank">YUI Compressor</a> که نسبت به سایر چلاننده‌‌های موجود از کارایی بهتری برخوردار بود و این برتری را تا مدتها حفظ کرد و هم اکنون که بیش از دو سال از انتشار نسخه‌ی اول آن می‌گذرد اکثر پروژه ها و فریم ورک های جاوااسکرپیت از این چلاننده برای چلاندن اسکریپت‌هایشان استفاده می‌کنند.</p>
<p>حدود یکی دو ماه پیش گوگل هم پا به عرصه رقابت گذاشت و چلاننده‌ی خودش را با نام <a href="http://code.google.com/closure/compiler/" target="_blank">Closure Compiler</a> عرضه کرد. این چلاننده از تکنیک های جدیدی استفاده میکند که باعث شده نرخ فشرده سازی آن حدود 10 تا 20 درصد از YUI بیشتر باشد. از نکات قابل توجه در این چلاننده این است که قابلیت شناسایی و حذف کدهای بلااستفاده(dead code) را از درون اسکریپت دارد.</p>
<p>چلاننده‌ی گوگل مشابه YUI یک برنامه Java است که از خط دستور اجرا میشود ولی علاوه بر این گوگل این برنامه را به صورت <a href="http://closure-compiler.appspot.com/home" target="_blank">اپلیکشن تحت وب</a> و <a href="http://code.google.com/closure/compiler/docs/gettingstarted_api.html" target="_blank">API</a> هم ارائه کرده است.</p>
<p>برای مقایسه‌ی تکنیک های بکار رفته در YUI Compressor و Closure Compiler دیدن این slideshow رو توصیه می‌کنم.</p>
<div id="__ss_2462617" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="Closure Compiler vs YUICompressor" href="http://www.slideshare.net/lifesinger/closure-compiler-vs-yuicompressor">Closure Compiler vs YUICompressor</a><object style="margin:0px" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=closure-compiler-vs-yui-compressor-091109210742-phpapp02&amp;rel=0&amp;stripped_title=closure-compiler-vs-yuicompressor" /><param name="allowfullscreen" value="true" /><embed style="margin:0px" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=closure-compiler-vs-yui-compressor-091109210742-phpapp02&amp;rel=0&amp;stripped_title=closure-compiler-vs-yuicompressor" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">documents</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/lifesinger">lifesinger</a>.</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1388/09/29/google-closure-compiler/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>مقایسه‌ی Git با Subversion</title>
		<link>http://farhadi.ir/blog/1388/06/23/git-vs-svn/</link>
		<comments>http://farhadi.ir/blog/1388/06/23/git-vs-svn/#comments</comments>
		<pubDate>Sun, 13 Sep 2009 22:32:57 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[توسعه‌ی وب]]></category>
		<category><![CDATA[DVCS]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[SCM]]></category>
		<category><![CDATA[Subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[VCS]]></category>
		<category><![CDATA[Version Control]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=171</guid>
		<description><![CDATA[امروز بعد از مدتها یادم اومدم وبلاگ هم دارم. گفتم یه چیزی بنویسم تا اینجا از این وضع در بیاد.
توی شرکت داریم پروژه‌ها رو از svn به git سوئیچ می‌کنیم. دیدم بهانه‌ی خوبیه تا درباره‌ی git بنویسم.
از اونجایی که اکثر برنامه‌نویس‌ها با svn آشنایی دارن به جای نوشتن در مورد git به مقایسه‌ی git با [...]]]></description>
			<content:encoded><![CDATA[<p>امروز بعد از مدتها یادم اومدم وبلاگ هم دارم. گفتم یه چیزی بنویسم تا اینجا از این وضع در بیاد.</p>
<p>توی شرکت داریم پروژه‌ها رو از svn به git سوئیچ می‌کنیم. دیدم بهانه‌ی خوبیه تا درباره‌ی git بنویسم.<br />
از اونجایی که اکثر برنامه‌نویس‌ها با svn آشنایی دارن به جای نوشتن در مورد git به مقایسه‌ی git با svn می‌پردازم. اینجوری راحت‌تر می‌تونید تصمیم بگیرید که آیا نیازی به تغییر سیستم کنترل سورس فعلیتون به git هست یا نه.</p>
<p>این روزها سیستم‌های توزیع شده‌ی کنترل سورس (Distributed Version Control) کم کم دارن جای سیستم‌های کنترل سورس سنتی متمرکز (Centralized) مثل svn رو می‌گیرن. از جمله git یکی از این سیستم‌های کنترل سورس توزیع شده است که محبوبیت زیادی پیدا کرده.<br />
قسمت عمده‌ای از تفاوت‌های git و svn برمی‌گرده به تفاوت مدل توزیع شده و مدل متمرکز، برای همین ابتدا این دو مدل رو توضیح میدم.<br />
<span id="more-171"></span></p>
<h3>مدل متمرکز</h3>
<p>در این مدل یک مخزن (Repository) داریم که روی یک سرور قرار می‌گیره که شامل کل پروژه با تاریخچه‌اش است. هر کس که می‌خواد روی پروژه کار کنه یک کپی از آخرین نسخه‌ی پروژه رو از سرور دریافت می‌کنه (همون working copy)، تغییراتی میده و بعد تغییراتش رو به سرور ارسال (commit) می‌کنه تا در مخزن قرار بگیره. همچنین می‌تونه آخرین تغییرات سایرین رو از مخزن دریافت (update) کنه و به این ترتیب هر کس می‌تونه آخرین نسخه‌ی پروژه رو روی کامپیوتر خودش داشته باشه.</p>
<p>با توجه به لزوم وجود سرور در این مدل به این مدل، مدل کلاینت-سرور هم میگن.</p>
<h3>مدل توزیع شده</h3>
<p>در این مدل نیازی به وجود سرور برای نگهداری مخزن نیست و هر کس به جای working copy یک مخزن از پروژه رو داره. که این مخزن میتونه شامل working directory هم باشه.</p>
<p>برای مثال با git وقتی یک نفر یک پروژه رو شروع می‌کنه یک مخزن روی کامپیوتر خودش ایجاد می‌کنه و شروع به کار میکنه. حالا نفر دوم می‌تونه از این مخزن یک کلون (clone) تهیه کنه به عبارت دیگه یک مخزن عین مخزن نفر اول روی کامپیوتر خودش ایجاد کنه و در توسعه پروژه مشارکت کنه. حالا هر یک از این دو نفر هر موقع که خواستند میتونن از مخزن یکدیگر تغییرات یکدیگر را دریافت (fetch) و یا برای دیگری تغییرات خود را ارسال (push) کنند و تغییرات را ادغام (merge) کنند. وقتی نفر سوم می‌خواد وارد پروژه بشه، از هر یک از دو مخزن نفرات قبل میتونه کلون تهیه کنه و کار رو شروع کنه و می‌تونه تغییرات خودش رو با هر یک از اونها مبادله کنه. و این روند ادامه پیدا میکنه.</p>
<p>در واقع در این روش مخزن بین تمام مشارکت کنندگان در پروژه توزیع شده، برای همین به این مدل، مدل توزیع شده گفته میشه.</p>
<p>حتما با خودتون فکر می‌کنید که این روش شاید برای یک گروه سه یا چهار نفره مناسب باشه ولی برای تیم های بزرگتر کارایی نداره چون هماهنگ کردن مخازن کار خیلی مشکلی میشه. در جواب باید گفت گرچه در مدل توزیع شده وجود سرور الزامی نیست ولی محدودیتی برای استفاده از این مدل به صورت کلاینت-سروری وجود نداره. یعنی شما می‌تونید یک مخزن روی یک سرور بگذارید و به صورت توافقی همه‌ی توسعه‌دهنده‌ها به جای مبادله تغییرات با یکدیگر، تغییرات را با مخزن روی سرور مبادله کنند. خوب حالا حتما با خودتون می‌گین این که همون مدل متمرکز شد! عجله نکنید. تا انتهای مطلب رو بخونید بعد قضاوت کنید.</p>
<h3>مزایای مدل توزیع شده</h3>
<ul>
<li><strong>عدم نیاز به شبکه</strong><br />
با توجه به اینکه در این روش مخزن روی کامپیوتر شما قرار داره برای انجام خیلی از عملیات‌ها نیازی به اتصال به شبکه نیست. مثلا commit کردن، log گرفتن، diff گرفتن، و خیلی عملیات‌های دیگه نیازی به ارتباط با شبکه نداره. که باعث کاهش ترافیک شبکه میشه و در عین حال این امکان رو به شما میده که در هنگامی که شبکه قطع است و یا هنگامی که با لپتاپ خود به مسافرتی و یا جایی می‌روید که دسترسی به شبکه ندارید همچنان به کار خودتون روی پروژه ادامه بدید.</li>
<li><strong>سرعت بیشتر</strong><br />
عدم نیاز به شبکه در انجام اکثر عملیات‌ها باعث افزایش قابل توجه سرعت در اینگونه عملیات‌ها میشه.</li>
<li><strong>مشارکت در پروژه </strong><strong>بدون نیاز به دسترسی کامیت </strong><br />
با توجه به ماهیت توزیع شده در این مدل برای مشارکت در یک پروژه نیازی به دسترسی کامیت نیست. به این صورت که شما یک clone از یک پروژه تهیه می‌کنید و تغییراتی را در آن می‌دهید و روی مخزن خود کامیت می‌کنید. حالا می‌تونید از یک نفر که دسترسی کامیت داره بخواهید که کامیت‌های شما رو بررسی کنه و اگر صلاح دونست توی مخزن اصلی merge کنه. در نتیجه بدون اینکه شما دسترسی مستقیم کامیت داشته باشید کامیت‌های شما با نام خودتان در مخزن اصلی ثبت میشه. این مزیت برای پروژه‌های بازمتن خیلی مفیده و به گسترش و توسعه پروژه با افزایش مشارکت داوطلبین کمک میکنه. بگذارید یک مثال عینی بزنم. من برای ارسال patch به پروژه cakephp که قبلا از svn استفاده میکردند فایل patch تغییرات رو ضمیمه‌ی تیکت کردم(<a href="https://trac.cakephp.org/ticket/6138" target="_blank">؟</a>). یکی از برنامه نویسان تغییرات رو بررسی و روی پروژه کامیت کرد(<a href="https://trac.cakephp.org/changeset/8057" target="_blank">؟</a>). در اینجور مواقع از اونجایی که svn این کامیت رو به نام شخص کامیت کننده ذخیره میکنه نه مولف اصلی، معمولا برای مشخص شدن نویسنده‌ی اصلی توی کامنت می‌نویسند &#8220;applying patch from x&#8221; و ضمن اینکه اگر تغییرات زیاد باشه بررسی تغییرات کار سختی میشه. حالا ببینیم git چطور این مشکل رو حل میکنه. بعد از اینکه cakephp به git منتقل شد من یک باگ گزارش دادم(<a href="http://code.cakephp.org/tickets/view/44" target="_blank">؟</a>) و برای نوشتن testcase برای این باگ یک fork از پروژه گرفتم، testcase رو نوشتم و کامیت کردم(<a href="http://thechaw.com/forks/farhadi/cakephp/commits/view/22f5d31e7940ad94569241fecc61427b0ae3a14d" target="_blank">؟</a>) و لینک تغییرات رو به تیکت اضافه کردم. یکی از برنامه نویسان تغییرات رو بررسی و در مخزن اصلی ادغام میکنه(<a href="http://code.cakephp.org/commits/view/1821efe0a43d502ae81a78968d0df21feb6ae497" target="_blank">؟</a>). اینجا git این کامیت رو با نام مولف اصلی و تاریخ اصلی تغییرات ذخیره میکنه و در عین حال نام کامیت کننده و تاریخ کامیت رو هم ذخیره میکنه. ضمن اینکه اینجا اگر تغییرات زیاد باشه میشه به کامیت‌های مختلف تفکیک بشه که هر کدوم توضیحات خودش رو داره و بررسی این تغییرات کار راحت تری میشه.</li>
<li><strong>کاهش خطر از دست رفتن اطلاعات</strong><br />
در این مدل با توجه به اینکه هر توسعه دهنده یک مخزن از پروژه رو داره در صورت ترکیدن سرور و از دست رفتن کل اطلاعات هیچ مشکلی پیش نمیاد و می‌تونید مجددا یکی از مخازن موجود رو روی سرور قرار داده و بدون هیچ مشکلی کار رو ادامه بدید.</li>
<li><strong>پشتیبانی از مدل‌های کاری(workflow) متعدد</strong><br />
با استفاده از سیستم های توزیع شده تقریبا هر نوع مدل کاری رو میشه پیاده سازی کرد. مثلا شما می‌تونید مثل سیستم های متمرکز به صورت کلاینت-سرور کار کنید. البته این مبحث خودش یک مقاله جداگانه رو می‌طلبه. اگر حوصله داشتید برای کسب اطلاعات بیشتر <a href="http://whygitisbetterthanx.com/#any-workflow" target="_blank">اینجا</a> و <a href="http://bazaar-vcs.org/Workflows" target="_blank">اینجا</a> رو مطالعه کنید.</li>
<li><strong>امکان داشتن مخزن خصوصی از یک پروژه</strong><br />
برای مثال شما می‌تونید یک clone از یک پروژه بگیرید و یکسری تغییرات خصوصی برای خودتون بدید ولی در پروژه اصلی اعمال نکنید. و در عین حال همیشه می‌تونید آخرین تغییرات پروژه اصلی رو روی مخزن خصوصی‌تان ادغام کنید.</li>
<li><strong>تمیزتر بودن مخزن اصلی</strong><br />
با توجه به اینکه در این روش کامیت‌ها را روی مخزن محلی خودتان انجام می‌دهید. در صورت بروز اشتباه در کامیت دیگه اون کامیت رو در مخزن سرور اصلی ادغام نمی‌کنید. ولی در سیستم هایی مثل svn در صورتی که اشتباها یک فایل cd.iso رو توی مخزن کامیت کنید. حتی بعد از حذفش هم حجم مخزن کاهش پیدا نمیکنه و اون فایل برای همیشه در تاریخچه مخزن باقی می‌مونه و حجم مخزن به مرور زمان در اثر این اشتباهات افزایش پیدا میکنه و تاریخچه‌ی مخزن شلوغ و کثیف میشه.</li>
</ul>
<h3>معایب مدل توزیع شده</h3>
<ul>
<li><strong>مشکل درک مفاهیم</strong><br />
گفته میشه اکثر افراد در درک مفاهیم سیستم‌های توزیع شده مشکل دارند و کمی طول می‌کشه تا بتونن بهش عادت کنند. البته علت اصلی اینه که اکثرا به سیستم‌های متمرکز عادت کردند و همون انتظاراتی رو از سیستم‌های توزیع شده دارند که از یک سیستم متمرکز دارند. این باعث میشه مثلا به نظرشون بیاد بعضی از مراحل و عملیات‌ها اضافه است.<br />
در صورتی که ساختار و نحوه عملکرد سیستم‌های توزیع شده رو زیربنایی یاد بگیرید درک مفاهیم اون خیلی برایتان ساده خواهد شد.</li>
<li><strong>مشکل کنترل دسترسی</strong><br />
با توجه به اینکه در مدل توزیع شده کل مخزن در اختیار توسعه دهندگان قرار می‌گیره هر کس که بتونه به یکی از این مخازن دسترسی داشته باشه به کل پروژه دسترسی پیدا میکنه. ولی در مدل متمرکز میشه مطمئن بود که فقط کسانی به مخزن دسترسی دارند که به مخزن سرور اصلی دسترسی داشته باشند. البته این مسئله در مورد پروژه‌های بازمتن مشکل به حساب نمیاد.</li>
</ul>
<p>امروزه سیستم‌های کنترل سورس توزیع شده‌ی متعددی وجود داره که هر کدوم طرفدارهای خاص خودش رو داره از جمله معروف‌ترین اونها <a href="http://git-scm.com/" target="_blank">Git</a> و <a href="http://bazaar-vcs.org/" target="_blank">Bazaar</a> و <a href="http://mercurial.selenic.com/wiki/" target="_blank">Mercurial</a> هستند.<br />
همه‌ی این سیستم‌ها تفاوت‌های گفته شده رو نسبت به سیستم‌های متمرکز دارند. علاوه بر این، این سیستم‌ها کم و بیش مزایای دیگری هم دارند که در این بین Git از جایگاه بهتری نسبت به بقیه برخوردار است.</p>
<h3>مزایای Git</h3>
<ul>
<li><strong>سرعت فوق العاده</strong><br />
یکی از اهداف اولیه طراحی git سرعت بوده. و از این نظر واقعا git موفق بوده.<br />
در کل سیستم‌های توزیع شده از سرعت بهتری نسبت به سیستم‌های متمرکز برخوردارند. و در بین سیستم‌های توزیع شده git بهترین جایگاه رو از نظر سرعت داره. یکی از دلایل سرعت git اینست که با زبان C نوشته شده که نسبت به زبان‌های سطح بالا نظیر python سرعت بهتری داره. (Bazaar و Mercurial با python نوشته شده‌اند.)</li>
<li><strong>حجم کم</strong><br />
حجم یک working directory به همراه مخزن در git به ندرت از یک working copy در svn بیشتر میشه. برای مثال مخزن Mozilla در svn چیزی حدود 12GB بوده در حالیکه حجم همین مخزن در git حدود 420MB بیشتر نیست. یعنی حدود 30 بار کوچکتر از svn. مخزن پروژه Ruby on Rails در git که شامل کل تاریخچه فایل‌هاست حدود 13MB بیشتر نیست درحالیکه حجم پروژه (بدون مخزن) 9MB است یعنی حجم کل مخزن فقط یک ونیم برابر حجم پروژه است. و مخزن همین پروژه قبلا در svn حدود 115MB بوده.<br />
حتی در بین سیستم‌های توزیع شده هم git از نظر حجم بهترین جایگاه رو داره.</li>
<li><strong>پایداری</strong><br />
معماری داخلی git از سادگی و پایداری فوق‌العاده‌ای برخورداره که تقریبا امکان خراب شدن مخزن در اون وجود نداره. ولی تا به حال موارد زیادی از خراب شدن خود به خود مخازن svn مشاهده شده.</li>
<li><strong>راحتی کار با شاخه ها</strong> <strong>(branch)</strong><br />
یکی از قابلیت‌های فوق العاده‌ی git پشتیبانی خیلی خوب از شاخه هاست. در git می‌تونید برای تست یک ایده‌ی جدید شاخه‌ی محلی بسازید و در حین کار هر زمان خواستید به شاخه اصلی برگردید و یکسری کامیت انجام دهید و مجددا به شاخه تست برگردید و می‌تونید هر زمان خواستید شاخه ها رو با هم ادغام کنید و یا حذف کنید. و تمام این عملیات‌ها بدون نیاز به ارتباط با سرور انجام می‌شود. و به خاطر معماری فوق العاده‌ی git در مقایسه با سایر سیستم‌ها از سرعت و کارایی فوق العاده ای برخوردار است.</li>
<li><strong>دنبال کردن محتوای فایل به جای نام فایل<br />
</strong>git محتوای فایل‌ها را دنبال می‌کند. یعنی اگر فایلی را بدون استفاده از دستورات git تغییر نام داده، جابه‌جا و یا کپی کنید git با توجه به این ویژگی، این عملیات را تشخیص داده و ثبت میکند و لذا تاریخچه مربوط به اینگونه فایل‌ها را حفظ می‌کند.</li>
<li><strong>کامیت با جزئیات بیشتر<br />
</strong>در git یک کامیت علاوه بر نام کامیت کننده و تاریخ کامیت شامل نام مولف و تاریخ تغییرات هم هست. برای مثال این قابلیت git باعث میشه که در اعمال patch ها نام مولف اصلی و تاریخ تغییرات حفظ شود.</li>
<li><strong>شلوغ نکردن working directory با پوشه‌های .git<br />
</strong>اگر با svn کار کرده باشید می‌دانید که svn در تمام پوشه‌های پروژه یک پوشه به نام .svn ایجاد می‌کند که باعث بوجود آمدن مشکلات زیادی می‌شود. مثلا اینکه نمی‌توانید شاخه‌ها را کپی کنید و باید از دستورات خود svn استفاده نمایید. و در صورت عدم استفاده از دستورات svn چنانچه تغییراتی در کپی بدهید، بر روی شاخه‌ی اصلی کامیت می‌شود و یا تغییرات شاخه‌ی اصلی روی کپی شما هم اعمال می‌شود. این مشکل معمولا برای اکثر برنامه نویسان تازه‌کار اتفاق می‌افتد.<br />
اما در git فقط یک شاخه به نام .git در پوشه‌ی اصلی پروژه ایجاد می‌شود که مانع از به وجود آمدن مشکلاتی نظیر مشکلات فوق می‌شود.</li>
<li><strong>نمایش میزان پیشرفت عملیات<br />
</strong>در اکثر عملیات‌های شبکه‌ای در git مراحل و میزان پیشرفت عملیات نمایش داده می‌شود و می‌توانید بفهمید چه میزان از کار انجام شده و چه مقدار باقی ماده است. اما در svn این امکان وجود ندارد.</li>
<li><strong>تنوع در مجموعه دستورات و امکانات (feature-rich)</strong><br />
درgit مجموعه دستورات متعددی (بالغ بر 140 دستور) وجود دارد که با یادگیری آنها می‌توان کارهایی را انجام داد که در سایر سیستم‌ها یا قابل انجام نیست و یا بسیار دشوار است. قابلیت‌های منحصر به فردی نظیر stage area و stash و local branching که با یادگیری آنها در روش کارتان تحولاتی ایجاد خواهد شد و دیگر قادر به برگشتن به سایر سیستم‌ها نخواهید بود.</li>
</ul>
<h3>معایب Git</h3>
<ul>
<li><strong>کدهای طولانی SHA1 به جای شماره‌های متوالی revision</strong><br />
در واقع این مورد ایراد به حساب نماید و حتی معماری git به گونه‌ای است که از این شناسه‌های SHA1 به عنوان امضای دیجیتال برای کامیت‌ها و سایر آبجکت‌های داخلی گیت استفاده شده که باعث بالا رفتن امنیت و جلوگیری از دستکاری مخازن خواهد شد.<br />
اما معمولا در شروع کار با git اولین چیزی است که، عجیب و غیرعادی به نظر می‌رسد و اکثر تازه‌کارها را دچار سردرگمی می‌کند.<br />
از آنجایی که در معماری توزیع شده کامیت‌ها در یک مکان انجام نمی‌شود امکان تخصیص شماره های منحصر به فرد و متوالی به کامیت‌ها وجود ندارد. در git از کدهای 40 کاراکتری SHA1 به عنوان شناسه‌ی کامیت استفاده می‌شود. از آنجایی که به خاطر سپردن این کدها کار دشواری است می‌توان فقط از چند کاراکتر اول آن استفاده کرد. و چنانچه این چند کاراکتر در مورد دو شناسه‌ تکراری نباشد git میتواند شناسه‌ی مورد نظر شما را پیدا کند. معمولا از 7 کاراکتر اول استفاده میشود که احتمال تکراری بودن آن در یک پروژه بسیار کم است.<br />
در git راه‌های مختلفی برای ارجاع به آبجکت‌های داخلی(از جمله کامیت‌ها) وجود دارد که به اصلاح به آن ها Treeish  گفته میشود. مثلا برای ارجاع به کامیت‌ها می‌توان از tag ها و یا میانبرهایی نظیر^ و ‍~ و @ استفاده کرد.</li>
<li><strong>عدم سازگاری دستورات با سیستم‌های سنتی</strong><br />
اکثر دستورات git یا عملکرد کاملا متفاوتی با دستورات هم نام خود در سیستم‌های دیگر نظیر svn دارند و یا اینکه اسامی متفاوتی با معادل‌های رایج در سیستم‌های دیگر دارند. و این باعث میشود برنامه نویسانی که به سیستم‌هایی نظیر svn عادت کرده‌اند در ابتدای کار با git دچار سردرگمی شوند. تعدد دستورات git که بالغ بر 140 دستور می‌شود نیز مزید بر علت است.</li>
<li><strong>امکان checkout جزئی وجود ندارد</strong><br />
در svn می‌توانید فقط از یک شاخه‌ از پروژه checkout بگیرید ولی در git این امکان وجود ندارد و باید کل پروژه clone گرفته شود. البته با استفاده از قابلیت submodule در git می‌توان قسمت‌های مختلف پروژه را در مخازن جداگانه ذخیره کرد و این مخازن را در مخزن اصلی به صورت submodule استفاده کرد. که در این حالت می‌توان برای کار کردن روی یکی از این قسمت‌ها به جای clone گرفتن از کل پروژه فقط از submodule مربوطه clone گرفت.</li>
<li><strong>امکان افزودن پوشه خالی به مخزن وجود ندارد</strong><br />
مبنای کار git بر اساس محتوای فایل‌هاست و در معماری git امکان تعریف پوشه‌ی خالی وجود ندارد. لذا برای رفع این مشکل معمولا به صورت قراردادی یک فایل خالی به نام empty در این پوشه‌ها قرار می‌دهند.</li>
<li><strong>عدم سازگاری با ویندوز</strong><br />
git را نویسنده‌ی لینوکس(لینوس تروالدز) برای میزبانی پروژه‌ی کرنل لینوکس نوشته است. و از همان ابتدا قابلیت حمل(portability) جزو اهداف پروژه نبوده است و فقط روی سیستم های ‎*nix اجرا می‌شود. و رسما از ویندوز پشتیبانی نمی‌کند. البته این مشکل امروز تا حدود زیادی با کمک پروژه msysgit برطرف شده است. msysgit  در واقع با پیاده سازی gcc و دستورات مورد نیاز در ویندوز قابلیت اجرا شدن git در ویندوز را فراهم میکند.</li>
<li><strong>کمبود رابط گرافیکی قوی</strong><br />
برای svn تاکنون رابط‌های گرافیکی فوق‌العاده‌ای نظیر TortoiseSVN نوشته شده است. ولی در مورد git هنوز در ابتدای راه هستیم. البته به تازگی نسخه‌های اولیه‌ای از TortoiseGit که تلاشی برای شبیه سازی رابط گرافیکی محبوب TortoiseSVN برای git است منتشر شده است که  هنوز تمام امکانات و دستورات git را پوشش نمی‌دهد.</li>
</ul>
<p>یکی از دلایلی که قبلا برنامه‌نویسان کمتر به سیستم‌های کنترل سورس توزیع شده روی می‌آوردند عدم پشتیبانی میزبان‌هایی نظیر <a href="http://sourceforge.net/" target="_blank">SourceForge</a> و <a href="http://code.google.com/" target="_blank">Google Code</a> بود. اما امروز تقریبا این مشکل حل شده است.<br />
هم اکنون SourceForge  از CVS و SVN و Git و Mercurial و Bazaar پشتیبانی می‌کند. و Google Code هم از SVN و Mercurial پشتیبانی میکند.<br />
<a href="https://github.com/" target="_blank">GitHub</a> هم به عنوان یک میزبان برای پروژه‌های Git محبوبیت زیادی پیدا کرده و البته بیشتر از اینکه یک میزبان باشه یک شبکه اجتماعی برای میزبانی کدهاست.</p>
<p>در نهایت اگر تصمیم گرفتید از git استفاده کنید. خوندن کتابهای <a href="http://peepcode.com/products/git-internals-pdf" target="_blank">Git Internals</a> و <a href="http://oreilly.com/catalog/9780596520120/" target="_blank">Version Control with Git</a> رو توصیه می‌کنم.</p>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1388/06/23/git-vs-svn/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>آزمون آنلاین توسعه‌ی وب</title>
		<link>http://farhadi.ir/blog/1387/12/26/online-webdev-quiz/</link>
		<comments>http://farhadi.ir/blog/1387/12/26/online-webdev-quiz/#comments</comments>
		<pubDate>Sun, 15 Mar 2009 21:10:08 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[توسعه‌ی وب]]></category>
		<category><![CDATA[Certification]]></category>
		<category><![CDATA[Quiz]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=172</guid>
		<description><![CDATA[اگر یادتون باشه حدود 2 یا 3 سال پیش سایت brainbench.com آزمون php رو رایگان کرده بود. امروز دوباره رفتم ببینم هنوز هم رایگانه یا نه.
آزمون php رایگان نبود. توی لیست آزمون های رایگانش گشتم ببینم چیزی داره که به درد ما بخوره. آزمون «مفاهیم توسعه‌ی وب» (Web Development Concepts) رو پیدا کردم. 40 تا [...]]]></description>
			<content:encoded><![CDATA[<p>اگر یادتون باشه حدود 2 یا 3 سال پیش سایت <a href="http://brainbench.com/" target="_blank">brainbench.com</a> آزمون php رو رایگان کرده بود. امروز دوباره رفتم ببینم هنوز هم رایگانه یا نه.</p>
<p>آزمون php رایگان نبود. توی <a href="http://www.brainbench.com/xml/bb/common/testcenter/freetests.xml" target="_blank">لیست آزمون های رایگانش</a> گشتم ببینم چیزی داره که به درد ما بخوره. <a href="http://www.brainbench.com/xml/bb/common/testcenter/taketest.xml?testId=778" target="_blank">آزمون «مفاهیم توسعه‌ی وب»</a> (Web Development Concepts) رو پیدا کردم. 40 تا سوال داشت با 3 دقیقه وقت برای هر سوال. واقعا سوال ها خوب طراحی شده بودند. اگر شما هم توی همین زمینه کار می‌کنید توانایی‌هاتون رو یک محک بزنید. برای رزومه هم خوبه. یک کاربرد خوب این آزمون برای کارفرماها اینه که میتونن برای استخدام نیرو از این آزمون استفاده کنند.</p>
<p>این هم <a href="http://www.brainbench.com/transcript.jsp?pid=8179825" target="_blank">نتیجه‌ی آزمون من</a>:</p>
<p><a href="http://farhadi.ir/blog/wp-content/uploads/2009/03/webdev-quiz-result.png"><img class="alignnone size-full wp-image-173" title="webdev-quiz-result" src="http://farhadi.ir/blog/wp-content/uploads/2009/03/webdev-quiz-result.png" alt="" width="462" height="350" /></a></p>
<p>راستی سال نو هم پیشاپیش تبریک، شاید تا سال دیگه فرصت نوشتن پیدا نکردم.</p>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1387/12/26/online-webdev-quiz/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>راهکارهایی برای بهینه سازی سایت</title>
		<link>http://farhadi.ir/blog/1387/10/06/website-performance-optimization/</link>
		<comments>http://farhadi.ir/blog/1387/10/06/website-performance-optimization/#comments</comments>
		<pubDate>Fri, 26 Dec 2008 18:32:27 +0000</pubDate>
		<dc:creator>علی</dc:creator>
				<category><![CDATA[توسعه‌ی وب]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[YSlow]]></category>

		<guid isPermaLink="false">http://farhadi.ir/blog/?p=39</guid>
		<description><![CDATA[برای سایت های پر بازدید، بهینه بودن سایت از اهمیت زیادی برخورداره. بهینه بودن یعنی اینکه سایت در کمترین زمان ممکن لود بشه و مصرف منابع سرور هم به حداقل ممکن برسه.
میشه فرایند بهینه سازی رو به دو بخش سمت کاربر و سمت سرور تقسیم کرد.
بهینه سازی سمت سرور یعنی بهینه کردن برنامه و کد [...]]]></description>
			<content:encoded><![CDATA[<p>برای سایت های پر بازدید، بهینه بودن سایت از اهمیت زیادی برخورداره. بهینه بودن یعنی اینکه سایت در کمترین زمان ممکن لود بشه و مصرف منابع سرور هم به حداقل ممکن برسه.</p>
<p>میشه فرایند بهینه سازی رو به دو بخش سمت کاربر و سمت سرور تقسیم کرد.<br />
بهینه سازی سمت سرور یعنی بهینه کردن برنامه و کد های سمت سرور برای اینکه حداقل منابع رو مصرف کنه و در حداقل زمان ممکن اجرا بشه. که این قسمت از بهینه سازی فعلا موضوع بحث ما نیست.<br />
و اما بهینه سازی سمت کاربر شامل کلیه اقداماتی است که برای کاهش مصرف  پهنای باند وافزایش سرعت لود شدن انجام میشه.</p>
<p>در ادامه این مقاله که در واقع برگرفته از کتاب «<a href="http://www.oreilly.com/catalog/9780596529307/" target="_blank">High Performance Web Sites</a>» هست می پردازیم به اهمیت و راهکارهای بهینه سازی سمت کاربر.<br />
لازم به ذکر است که این کتاب نوشته‌ی Steve Souders مسئول performance در یاهو می باشد.</p>
<h4><span id="more-39"></span><strong>اهمیت بهینه سازی سمت کاربر</strong></h4>
<p>از ملاک های اصلی جلب رضایت کاربران، کارایی و سرعت سایت است. بررسی ها نشان داده که کمتر از 20 درصد از زمان بارگزاری سایت صرف لود شدن html میشود و مابقی یعنی بیش از 80 درصد از  زمان، صرف بارگزاری آنچه درون صفحه است میشود. که توجه به بهینه سازی این قسمت (ملحقات صفحه) تا حدود زیادی سرعت و کارایی سایت را افزایش میدهد.</p>
<p>سه دلیل عمده برای اهمیت بهینه سازی ملحقات صفحه وجود دارد:</p>
<ol>
<li>پتانسیل بیشتری برای بهینه سازی ملحقات وجود دارد. کاهش پنجاه درصدی آن حدود 40 درصد در افزایش سرعت سایت تاثیر دارد درحالی که کاهش 50 درصدی حجم html تاثیرش کمتر از ده درصد است.</li>
<li>بهینه سازی ملحقات صفحه، زمان و منابع کمتری نیاز دارد نسبت به بهینه سازی سمت سرور (شامل تغییر معماری و کدنویسی مجدد، یافتن و رفع مشکلات و گلوگاه ها در کد، اصلاحات سخت افزاری و قرار دادن دیتابیس ها بر روی سرور های مجزا و &#8230; )</li>
<li>در عمل ثابت شده که این روش خوب جواب می دهد.  بیش از 50 تیم در یاهو به این روش توانستند حدود 25 درصد سرعت سایت ها را افزایش دهند.</li>
</ol>
<h4>و اما راهکارها:</h4>
<ol>
<li><strong>کاهش تعداد درخواست های HTTP </strong>
<ul>
<li>استفاده از تکنیک <a href="http://www.alistapart.com/articles/sprites/" target="_blank">CSS Sprites</a> که موجب کاهش تعداد تصاویر استفاده شده در css میشود.</li>
<li>الحاق فایلهای css به یکدیگر و همچنین اسکریپت ها</li>
<li>استفاده از تکنیک inline image (البته این تکنیک در IE پشتیبانی نمیشود)</li>
</ul>
</li>
<li><strong>استفاده از CDN</strong><br />
یک CDN مجموعه ای از وبسرورهاست که در نقاط مختلف دنیا توزیع شده اند و معمولا محتوای static رو میزبانی می‌کنند. تا بازدید کننده‌ها بتوانند از نزدیکترین سرور فایل ها را دریافت کنند. این تکنیک برای سایت های کوچک مقرون به صرفه نیست.</li>
<li><strong>افزودن Expires Header</strong><br />
مرورگرها میتوانند پاسخ درخواست های HTTP را کش کنند. با ارسال هدر Expires میتوان به مرورگر گفت که پاسخ را تا چه زمانی کش کند. برای مثال برای محتوای استاتیک میتوان این مقدار را بر روی یکسال گذاشت تا در درخواست های بعدی مرورگر از کش استفاده نماید.</li>
<li><strong>استفاده از gzip</strong><br />
تقریبا اکثر مرورگرها از gzip پشتیبانی میکنند. فشرده سازی gzip بر روی محتوای متنی نظیر css ها و اسکریپت ها و html کارایی خوبی دارد و بیش از 50 درصد حجم درخواست ها را کاهش میدهد.</li>
<li><strong>stylesheet ها را در ابتدای صفحه قرار دهید.</strong><br />
در بعضی مرورگرها درصورتی که stylesheet در انتهای صفحه باشه باعث میشه که محتوای صفحه دوبار رندر بشه و زمان بیشتری صرف بشه و ضمنا دفعه اول بدون style رندر میشه که ظاهر خوشایندی نداره. در بعضی مرورگرها هم موجب  میشه رندر بعد از لود شدن محتوا و ملحقات صفحه انجام بشه که باعث میشه ابتدا یک صفحه خالی نمایش داده بشه و رندر با کمی تاخیر انجام بشه.<br />
ضمنا قرار دادن stylesheet ها در ابتدای صفحه موجب میشه رندر به شکل مطلوبی و به صورت تدریجی همزمان با لود شدن محتوا انجام بشه.</li>
<li><strong>اسکریپت‌ها را در انتهای صفحه قرار دهید.</strong><br />
قرار دادن اسکریپت‌ها در ابتدای صفحه باعث میشه جلوی رندر شدن و دانلود شدن سایر محتویات صفحه تا اتمام لود شدن اسکریپت گرفته بشه.<br />
و اما قرار دادن اسکریپت‌ها در انتهای صفحه باعث میشه ابتدا محتوا رندر بشه و سپس سایر ملحقات و اسکریپت ها در پس زمینه لود بشه.</li>
<li><strong>از CSS Expression ها پرهیز کنید<br />
</strong>CSS Expression ها فقط در IE پشتیبانی می‌شوند. با استفاده از این قابلیت میتوان برای مقدار دادن به یک خصوصیت در CSS از جاوااسکریپت استفاده کرد. و این کد اسکریپت در مواقعی نظیر resize شدن صفحه و یا حرکت موس مجددا مقدار رو محاسبه میکنه. این اجرای مکرر میتونه باعث کاهش کیفیت و یا حتی هنگ شدن مرورگر بشه. پس بهتره از این CSS Expression ها استفاده نکنید.</li>
<li><strong>جاوااسکریپت ها و CSS ها را از HTML جدا کنید</strong><br />
گرچه اینکار قاعده شماره 1 رو نقض میکنه ولی با توجه به اینکه با جدا کردن CSS و JS ها و ذخیره اونها در فایل‌های استاتیک میشه قواعد 2 و 3 و 4 رو در موردشون بکار بست پس این کار به صرفه است.</li>
<li><strong>تعداد DNS Lookup ها را کم کنید</strong><br />
مرورگرها برای ارتباط با سرورها از IP اونها استفاده می‌کنند بنابراین مجبورند به ازای هر Hostname ابتدا یک درخواست به DNS سرور ارسال کنند و IP رو بدست بیارند. ضمن اینکه مرورگر میتونه از قابلیت Keep-Alive در مورد درخواست‌هایی که مربوط به یک Hostname هستند استفاده کنه که باعث میشه چندین درخواست از طریق یک کانکشن انجام بشه.<br />
پس بهتره محتویات سایتتون از Hostname های مختلف نباشه. (دقت کنید که www.example.com و example.com هم دو Hostname متفاوت هستند)</li>
<li><strong>جاوا اسکریپت ها را بچلانید</strong><br />
چلاندن(Minify) یعنی حذف اضافات (شامل کامنت‌ها، فضاها و اینترهای اضافی) از درون اسکریپت‌ها برای کاهش حجم فایل. البته یک گام فراتر هم میشه رفت با استفاده از پیچوندن (Obfuscation) که در این روش علاوه بر حذف اضافات، شناسه‌های استفاده شده در کد رو هم با شناسه‌های کوتاهتر جایگزین میکنند.<br />
روش چلاندن رو در مورد CSS هم میشه به کار برد ولی تاثیرش در مورد CSS ها کمتره. البته در مورد CSS میشه با بهینه کردن کد تا حدی از حجم CSS کم کرد. (در این مورد آقایان <a href="http://weblog.alvanweb.com/2005/08/17/css-shorthand/" target="_blank">الوانی</a> و <a href="http://weblog.corelist.net/archives/1387/02/17/css-shorthands/" target="_blank">ستاری</a> به طور مفصل توضیح دادند.)</li>
<li><strong>از Redirect کردن پرهیز کنید</strong><br />
هر Redirect مستلزم یک درخواست اضافه است و ضمنا این درخواست به صورت موازی هم نیست یعنی تا کامل نشده درخواست‌های بعدی ارسال نمی‌شوند. پس تا جائیکه ممکنه از Redirect پرهیز کنید.</li>
<li><strong>اسکریپت‌های تکراری را حذف کنید</strong><br />
گاهی ممکنه پیش بیاد که یک اسکریپت دو بار در صفحه درج شده باشه مثلا توی کار تیمی ممکنه یک نفر یک اسکریپت رو در یک جای صفحه درج کنه و یک نفر دیگه که از این موضوع خبر نداره مجدد اون رو در جای دیگه ای درج کنه.<br />
این کار دو تا مشکل ایجاد میکنه. یکی اینکه تعداد درخواست‌های HTTP افزایش پیدا میکنه و دو اینکه زمان اضافه ای صرف اجرای مجدد اون اسکریپت میشه. البته مورد اول فقط در IE و اون هم در حالتی که اسکریپت قابل کش شدن نباشه اتفاق میافته.</li>
<li><strong>پیکربندی ETag ها</strong><br />
مرورگرها از هدر ETag برای کش کردن محتوای استاتیک تا زمانی که تغییر نکرده استفاده می‌کنند (مشابه هدر Last-Modified). ولی ETag در صورتی که سایت بر روی بیش از یک سرور میزبانی شده باشد میتواند مشکل ساز شود. مثلا آپاچی به طور پیشفرض برای تولید ETag از «inode &#8211; حجم &#8211; زمان ویرایش» استفاده میکنه و inode در مورد یک فایل روی سرورهای مختلف فرق میکنه و در صورتی که مرورگر یک فایل رو از یک سرور دریافت کنه و در مراجعه بعدی به اون فایل برای چک کردن تغییرات از سرور دیگری استفاده کنه، با توجه به اختلاف ETag ها، سرور مجددا فایل رو میفرسته که باعث میشه مرورگر از کش استفاده نکنه. IIS هم مشکل مشابهی داره.<br />
اما راهکار اینه که یا کلا ETag رو حذف کنید و یا اینکه اصلاحش کنید برای مثال در آپاچی باید inode رو از ETag حذف کنید. (این کار رو با htaccess میشه انجام داد.)</li>
<li><strong>Ajax را قابل کش شدن کنید</strong><br />
یک برنامه‌ی وب دویی را در نظر بگیرید که مثلا برای لود کردن لیست ایمیل‌ها از Ajax استفاده میکند. در این حالت میتوان تا زمانی که لیست آدرس ها تغییر نکرده این درخواست را با استفاده از هدر Expires قابل کش کرد.<br />
ضمنا قواعد 4، 9، 10، 11 و 13 هم در مورد درخواست‌های اجکسی قابل استفاده هستند.</li>
</ol>
<p>اینها مواردی بود که در کتاب ذکر شده بودند. بعدها موارد دیگه ای هم به اینها اضافه شد و الان تعدادش به 34 مورد رسیده که میتونید <a href="http://developer.yahoo.com/performance/index.html#rules" target="_blank">اینجا</a> ببینید.</p>
<p>یاهو یک پلاگین برای فایرفاکس برای چک کردن این فاکتورها نوشته به نام <a href="http://developer.yahoo.com/yslow/" target="_blank">YSlow</a> که البته با Firebug کار میکنه.<br />
این پلاگین بر اساس این فاکتورها کیفیت سایت شما رو چک میکنه و مواردی که رعایت نشدند رو مشخص میکنه و یک نمره هم از 100 به سایت شما میده.</p>
<p>ابزارهای مختلفی وجود داره که پیاده سازی این موارد رو ساده میکنه.<br />
مثلا برای چلاندن جاوااسکریپت‌ها (مورد 10) می‌تونید از ابزارهایی مثل <a href="http://www.crockford.com/javascript/jsmin.html" target="_blank">JSMin</a> و <a href="http://dean.edwards.name/packer/" target="_blank">Packer</a> و <a href="http://www.julienlecomte.net/yuicompressor/" target="_blank">YUI Compressor</a> استفاده کنید.<br />
ابزارهایی هم هستند که با نصب اونها روی سایت به صورت خودکار بعضی از این موارد روی سایت شما اعمال میشوند. مثل <a href="http://code.google.com/p/minify/" target="_blank">Minify</a> و <a href="http://aciddrop.com/php-speedy/" target="_blank">PHPSpeedy</a> و <a href="http://farhadi.ir/works/smartoptimizer" target="_blank">SmartOptimizer</a>.</p>
<p>برای مثال <a href="http://farhadi.ir/works/smartoptimizer" target="_blank">SmartOptimizer</a> می‌تونه موارد 1 و 3 و 4 و 10 و 13 رو روی سایت شما اعمال کنه و نمره YSlow شما رو حدود  10-20 واحد افزایش بده.</p>
]]></content:encoded>
			<wfw:commentRss>http://farhadi.ir/blog/1387/10/06/website-performance-optimization/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
	</channel>
</rss>

