2013年8月25日星期日

【DevOps】为什么我们永远疲于奔命?

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
【DevOps】为什么我们永远疲于奔命?  阅读原文»

【DevOps】为什么我们永远疲于奔命?

【DevOps】谁说大象不能跳舞?一文之后,本文对DevOps的理念作进一步探讨。

最近在读一本书Project Phoenix,用小说的方式来描述了作为IT部门总裁的主人公临危受命,

面对IT开发和运维中出现的种种危机,在险峻的情况下采用新的管理理念,从而带领IT团队从低谷走向成功的故事。书中的一些场景,我是再熟悉不过了。有时候也不禁想,如果自己身在其中,会如何应对呢?

这本书也引用了很多DevOPs的理念,故事一波三折,其中的道理很耐人寻味。

话说该公司的IT部门是最备受责难的一个部门。很多商业计划因为IT不给力而拖延,IT环境极其不稳定,大小问题接连不断。IT每天忙于救火而疲于奔命。人员士气低落,各部门各自为战。出了事互相指责。

主人公在一位高人的指点下,开始了卓有成效的改革之旅。其中很重要的一个课题就是,到底根本问题出在哪里呢?为什么永远都觉得在疲于奔命?

他们从把工作分类开始,一步步得找到了症结所在。大体分四类工作:

Business Projects

比如其他部门的要上一个商业应用或者新的商业流程,需要IT提供软硬件环境,实施设计开发并运维。这类项目是有其他部门为实现某种商业目的来驱动的。

Internal Projects

往往指由IT内部驱动的项目,软件更新换代、扩容、安全措施、提高IT环境的稳定性、性能等等。

Change

ProductionEnvironment的有计划的升级,改动等等

Unplanned Work

一些突发情况,比如系统或应用的中断等等

上面的图揭示了一个恶性循环。

第一象限:因为商业计划往往时间紧、任务急,IT手忙脚乱把活干了,为了节省时间人力走了很多捷径,造成了系统稳定性的降低。为日后埋下了隐患。

第二象限:因为忙着赶第一象限的活儿,本来应该做的InternalProject就被拖延了。软件补丁和升级不及时,系统没有很好的优化和长期的计划,直接造成的系统稳定性、性能等的降低。

第三象限:因为没有很有效的ChangeControl,部门之间对改动互不知晓,还由于系统不稳定造成很多计划中的Change失败。从而累积了越来越多的问题

第四象限:由于前三个象限中问题产生的雪球效应,很多意外情况就不可避免的发生了。解决这些意外情况的成本是非常高的,因为打乱了本来的计划,造成了其他三个象限工作的拖延。从而又产生了新的一轮的恶性循环。

问题的症结找到了,那么如何入手解决呢。主人公Bill一连下了几记重拳:

建立高效的ChangeControl流程

这个流程开始的时候很不容易,因为人们习惯了各行其是,觉得Change Control太繁琐复杂。但这个流程是必须的,它可以评估改动的风险,防止出现意外情况。

暂时冻结Business Projects

短期的冻结,给了IT人员调整优化系统的喘息之机,从而能实施一些Internal Project来稳定IT环境。同时为新的BusinessProjects做好准备。

定位瓶颈

该书中描述了一位技术大拿Brent,总是在关键时候力挽狂澜。在很多情况下,少了Brent事情就干不成。主人公Bill意识到了如果不解决这个瓶颈,整个IT团队的生产力都要受到个人的影响。于是采取了一系列的措施解决这个问题。比如:最佳合理利用Brent的时间,避免很多琐事的干扰;培养一个梯队来承担Brent的任务,做好知识和经验的传承。

几套组合拳下来,很明显的减少了Unplanned Work,从而遏制住了恶性循环,为下一步的流程优化打下了基础。更重要的是增加了团队间的凝聚力和信心。

除此之外,书中反复强调了一个有重大意义的理念,就是以流水线的方式来开发和管理IT环境。我们会在下文中详细介绍。

本文出自 "坐看云起" 博客,请务必保留此出处http://frankfan.blog.51cto.com/6402282/1282559

解读ContentResolver和ContentProvider  阅读原文»

解读ContentResolver和ContentProvider
1. ContentProvider的概述
ContentProvider:
(Official Definition)Content providers manage access to a structured set of data. They encapsulate the data, and provide mechanisms for defining data security. Content providers are the standard interface that connects data in one process with code running in another process.
由官方的定义我们可以得知它是一个管理访问结构化数据的机制。我们系统中有些数据很重要,不能让人随便访问,但是因为比较有价值,所以很多应用程序需要用到它,这是就可通过ContentProvider这个机制,压缩数据,提供安全定义、访问数据的机制。该机制提供一个借口,使得应用程序能从该进程访问另外一个应用程序的数据。
不仅是系统重要的数据,如果我们开发过程中有数据也是比较重要,但是需要提供给多个程序访问,这个时候也可以用到ContentProvider机制,把我们的数据的增删改查分装在ContentProvider的增删改查中,并增加相应的安全机制,使得用户可我们规定的安全机制下访问我们的数据。
ContentProvider还有一个重要的特点就是它是可以使得某些数据可以被跨进程访问,一般我们的数据库是不可跨进程被访问,因为数据库一般的数据是属于某个应用程序的,如果其他程序可以随意访问其数据库,这是很危险的,但是如果该应用程序的数据想分享给其他应用程序,那么就可以通过建立一个ContentProvider,规定一些安全机制,屏蔽一些比较重要的数据被访问,或是规定访问权限,比如只可读不可写等,使其他应用程序在有限制的前提下访问我们的数据。这样做就会起到对数据进行保护同时又能使得有用的数据能被分享的作用。
2. ContentResolver和ContentProvider的使用方法
2.1 ContentResolver的使用方法:
首先,我们得了解如何通过ContentResolver来对系统或我们自定义的ContentProvider进行交互,通常,我们常用到的是访问系统的数据,常见的有通讯录、日历、短信、多媒体等,下面以通过ContentResolver获取系统的通讯录为例子,简单演示是如何使用ContentResolver的:
1、从当前Activity获取系统的ContentResolver;
2、使用ContentProvider的insert、delete、update、query方法对ContentProvider的内容进行增删改查;
3、如果是使用query是的到一个Cursor的结果集,通过该结果集可以获得我们查询的结果。
packagecth.android.contentprovide;
importandroid.annotation.SuppressLint;
importandroid.app.Activity;
importandroid.content.ContentResolver;
importandroid.database.Cursor;
importandroid.os.Bundle;
importandroid.provider.ContactsContract;
importandroid.util.Log;
importandroid.widget.ListAdapter;
importandroid.widget.ListView;
importandroid.widget.SimpleCursorAdapter;
*该类是演示利用ContentProvider,获取手机的联系人信息。
*使用ContentProvide的步骤:
*1、从当前Activity获取系统的ContentResolver;
*2、使用ContentProvider的insert、delete、update、query方法对ContentProvider的内容进行增删改查;
*3、如果是使用query是的到一个Cursor的结果集,通过该结果集可以获得我们查询的结果。
publicclassMainActivity extendsActivity {
privateListView contactsList;
@SuppressLint("InlinedApi")
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main); //不使用inflate XML文件方法,而是使用动态生成控件。
contactsList = newListView(MainActivity.this);
ContentResolver cr = getContentResolver(); //获取ContentResolver
Cursor cursor = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
null, null, null); //查询系统的联系人信息
Log.i("cth", cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME) + "");
@SuppressWarnings("deprecation")
ListAdapter la = newSimpleCursorAdapter(MainActivity.this,
android.R.layout.simple_list_item_1, cursor,
newString[] {ContactsContract.Contacts.DISPLAY_NAME_PRIMARY },
newint[] { android.R.id.text1 }); //建立列表适配器,把cursor关联进来
contactsList.setAdapter(la); //把ListVIew与适配器绑定
setContentView(contactsList); //动态生成ListView
2.2 常用的系统URI
访问系统提供?p>阅读更多内容

没有评论:

发表评论