在【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
package cth.android.contentprovide; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ContentResolver; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import android.util.Log; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleCursorAdapter; *该类是演示利用ContentProvider,获取手机的联系人信息。 *使用ContentProvide的步骤: *1、从当前Activity获取系统的ContentResolver; *2、使用ContentProvider的insert、delete、update、query方法对ContentProvider的内容进行增删改查; *3、如果是使用query是的到一个Cursor的结果集,通过该结果集可以获得我们查询的结果。 public class MainActivity extends Activity { private ListView contactsList; @SuppressLint ( "InlinedApi" ) protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); //setContentView(R.layout.activity_main); //不使用inflate XML文件方法,而是使用动态生成控件。 contactsList = new ListView(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 = new SimpleCursorAdapter(MainActivity. this , android.R.layout.simple_list_item_1, cursor, new String[] {ContactsContract.Contacts.DISPLAY_NAME_PRIMARY }, new int [] { android.R.id.text1 }); //建立列表适配器,把cursor关联进来 contactsList.setAdapter(la); //把ListVIew与适配器绑定 setContentView(contactsList); //动态生成ListView |
没有评论:
发表评论