【delphiui编辑工具源码】【抖音测评源码】【开奖走势分析源码】mai源码

2024-11-19 06:25:43 来源:licmanager源码 分类:热点

1.android的Handler中sendEmptyMessage与sendMessage的区别?
2.一文带你梳理Clang编译步骤及命令
3.什么是云服务

mai源码

android的Handler中sendEmptyMessage与sendMessage的区别?

       一、Handler的定义:

       主要接受子线程发送的数据, 并用此数据配合主线程更新UI.

       解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发, 比如说, 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。 如果此时需要一个耗时的delphiui编辑工具源码操作,例如: 联网读取数据, 或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,,如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,,会收到Android系统的一个错误提示 "强制关闭". 这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,,Android主线程是线程不安全的,也就是说,更新UI只能在主线程中更新,子线程中操作是危险的. 这个时候,Handler就出现了.,来解决这个复杂的问题 , 由于Handler运行在主线程中(UI线程中), 它与子线程可以通过Message对象来传递数据, 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象,(里面包含数据) , 把这些消息放入主线程队列中,配合主线程进行更新UI。

       二、Handler一些特点

       handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),

       它有两个作用: (1): 安排消息或Runnable 在某个主线程中某个地方执行, (2)安排一个动作在不同的线程中执行

       Handler中分发消息的一些方法

       [html] view plain copy

       post(Runnable)

       postAtTime(Runnable,long)

       postDelayed(Runnable long)

       sendEmptyMessage(int)

       sendMessage(Message)

       sendMessageAtTime(Message,long)

       sendMessageDelayed(Message,long)

       以上post类方法允许你排列一个Runnable对象到主线程队列中,

       sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.

       三、Handler实例

       (1) 子类需要继承Hendler类,并重写handleMessage(Message msg) 方法, 用于接受线程数据

       以下为一个实例,它实现的功能为 : 通过线程修改界面Button的内容

       [html] view plain copy

       public class MyHandlerActivity extends Activity {

       Button button;

       MyHandler myHandler;

       protected void onCreate(Bundle savedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.handlertest);

       button = (Button) findViewById(R.id.button);

       myHandler = new MyHandler();

       // 当创建一个新的Handler实例时, 它会绑定到当前线程和消息的队列中,开始分发数据

       // Handler有两个作用, (1) : 定时执行Message和Runnalbe 对象

       // (2): 让一个动作,在不同的线程中执行.

       // 它安排消息,用以下方法

       // post(Runnable)

       // postAtTime(Runnable,long)

       // postDelayed(Runnable,long)

       // sendEmptyMessage(int)

       // sendMessage(Message);

       // sendMessageAtTime(Message,long)

       // sendMessageDelayed(Message,long)

       // 以上方法以 post开头的允许你处理Runnable对象

       //sendMessage()允许你处理Message对象(Message里可以包含数据,)

       MyThread m = new MyThread();

       new Thread(m).start();

       }

       /**

       * 接受消息,处理消息 ,此Handler会与当前主线程一块运行

       * */

       class MyHandler extends Handler {

       public MyHandler() {

       }

       public MyHandler(Looper L) {

       super(L);

       }

       // 子类必须重写此方法,接受数据

       @Override

       public void handleMessage(Message msg) {

       // TODO Auto-generated method stub

       Log.d("MyHandler", "handleMessage......");

       super.handleMessage(msg);

       // 此处可以更新UI

       Bundle b = msg.getData();

       String color = b.getString("color");

       MyHandlerActivity.this.button.append(color);

       }

       }

       class MyThread implements Runnable {

       public void run() {

       try {

       Thread.sleep();

       } catch (InterruptedException e) {

       // TODO Auto-generated catch block

       e.printStackTrace();

       }

       Log.d("thread.......", "mThread........");

       Message msg = new Message();

       Bundle b = new Bundle();// 存放数据

       b.putString("color", "我的");

       msg.setData(b);

       MyHandlerActivity.this.myHandler.sendMessage(msg); // 向Handler发送消息,更新UI

       }

       }

       }

       例外一个案例:

       [html] view plain copy

       package com.example.span.view;

       import java.util.LinkedList;

       import android.app.AlertDialog;

       import android.content.ComponentName;

       import android.content.Context;

       import android.content.DialogInterface;

       import android.content.Intent;

       import android.graphics.Canvas;

       import android.graphics.Paint;

       import android.graphics.Point;

       import android.graphics.RectF;

       import android.os.Handler;

       import android.os.Message;

       import android.util.AttributeSet;

       import android.view.KeyEvent;

       import android.view.View;

       import android.widget.Toast;

       import com.example.span.view.domain.Block;

       /

**

       * -6-6 上午9::

       

*

       * @author 乔晓松

       */

       public class GameView extends View {

       public static boolean flag = true;

       public static Block block;

       public Handler handler;

       public static int dir = 2;

       public static final int DIRTOP = -1;

       public static final int DIRLEFT = -2;

       public static final int DIRDOWN = 1;

       public static final int DIRRIGHT = 2;

       public static int descount = 2;

       public Canvas canvas;

       public static Food food;

       public LinkedList points = new LinkedList();

       public LinkedList getPoints() {

       return points;

       }

       public void setPoints(LinkedList points) {

       this.points = points;

       }

       public GameView(Context context, AttributeSet attrs) {

       super(context, attrs);

       block = new Block(this);

       for (int i = 0; i < 3; i++) {

       Point point = new Point(block.getCx(), block.getCy());

       block.setCx(block.getCx() - );

       points.addLast(point);

       }

       food = new Food(this);

       handler = new Handler() {

       @Override

       public void handleMessage(Message msg) {

       super.handleMessage(msg);

       switch (msg.what) {

       case DIRLEFT:

       if (msg.what + descount != 0) {

       descount = -2;

       block.moveLeft();

       } else {

       block.moveRight();

       }

       break;

       case DIRRIGHT:

       if (msg.what + descount != 0) {

       descount = 2;

       block.moveRight();

       } else {

       block.moveLeft();

       }

       break;

       case DIRTOP:

       if (msg.what + descount != 0) {

       descount = -1;

       block.giveUp();

       } else {

       block.downLoad();

       }

       break;

       case DIRDOWN:

       if (msg.what + descount != 0) {

       descount = 1;

       block.downLoad();

       } else {

       block.giveUp();

       }

       break;

       case -3:

       Toast.makeText(getContext(), "Game Over", Toast.LENGTH_LONG)

       .show();

       new AlertDialog.Builder(getContext())

       .setTitle("游戏提示")

       .setMessage("Game Over")

       .setPositiveButton("退出",

       new DialogInterface.OnClickListener() {

       @Override

       public void onClick(

       DialogInterface dialog,

       int which) {

       Thread.currentThread().stop();

       }

       })

       .setNegativeButton("返回菜单",

       new DialogInterface.OnClickListener() {

       @Override

       public void onClick(

       DialogInterface dialog,

       int which) {

       Intent intent = new Intent();

       intent.setAction("android.intent.action.MAI");

       intent.addCategory("android.intent.category.LAUNCHER");

       intent.setFlags(0x);

       intent.setComponent(new ComponentName(

       "com.example.span",

       "com.example.span.SpanActivity"));

       getContext().startActivity(intent);

       }

       }).show();

       break;

       }

       }

       };

       new Thread(new Runnable() {

       @Override

       public void run() {

       while (flag) {

       try {

       Thread.sleep();

       handler.sendEmptyMessage(dir);

       } catch (InterruptedException e) {

       e.printStackTrace();

       }

       }

       handler.sendEmptyMessage(-3);

       }

       }).start();

       }

       @Override

       public boolean onKeyDown(int keyCode, KeyEvent event) {

       System.out.println(keyCode);

       return super.onKeyDown(keyCode, event);

       }

       @Override

       protected void onDraw(Canvas canvas) {

       super.onDraw(canvas);

       this.canvas = canvas;

       food.chsw(canvas);

       /

*

       * if (descount == 2) { chsw(); } else { if (points.contains(new

       * Point(, ))) { System.out.println("吃掉食物了,,.."); } else { chsw(); }

       * }

一文带你梳理Clang编译步骤及命令

       摘要: 本文简单介绍了Clang编译过程中涉及到的步骤和每个步骤的产物,并简单分析了部分影响预处理和编译成功的部分因素。

       本文简单介绍部分Clang和LLVM的编译命令。更关注前端部分(生成 IR 部分)。

1. Clang编译步骤概览

       我们可以使用命令打印出来Clang支持的步骤,如下:

clang-ccc-print-phasestest.c+-0:input,"test.c",c+-1:preprocessor,{ 0},cpp-output+-2:compiler,{ 1},ir+-3:backend,{ 2},assembler+-4:assembler,{ 3},object5:linker,{ 4},image

       根据上面的介绍,可以根据每一部分的结果,分为5个步骤(不包含上面的第0步):preprocessor、compiler、backend、assembler、linker等。

       具体到 Clang 中每一步骤生成的结果文件。我们可以使用下面的示意图来表示:

       说明:上面的示意图以Clang编译一个C文件为例,介绍了Clang编译过程中涉及到的中间文件类型:

       (1) test.c 为输入的源码(对应步骤 0);

       (2) test.i 为预处理文件(对应步骤 1 的输出,cpp-output 中,cpp 不是指 C++ 语言,而是 c preprocessor 的 缩写);

       (3) test.bc 为 bitcode文件,是clang的一种中间表示(对应步骤 2 的输出);

       (4) test.ll 为一种文本化的中间表示,可以打开来看的(对应步骤 2 的输出, 和 .bc 一样都是中间表示,可以相互转化);

       (5) test.s 为汇编结果(对应步骤 3 的输出);

       (6) test.o 为单文件生成的二进制文件(对应步骤 4 的输出);

       (7) image 为可执行文件(对应步骤 5 的输出)。

       注意:示意图画的也并不完整,如下介绍:

       (1) 箭头所指的抖音测评源码方向,表示可以从一种类型的文件,生成箭头所指的文件类型;

       (2) 图中箭头并没有画完,比如可以从 test.c 生成 test.s, test.o 等。如果将上面的示意图当做一种 有向图,那么基于 箭头 所指的方向,只要 节点能连接的点,都是可以做转换的;

       (3) 图中的实线和虚线,只是表示本人关心的Clang编译器中的内容,并没有其他的含义,本文也只介绍图中实线部分的内容,虚线部分的内容不做介绍。

2. 转换命令集合

       下面介绍部分涉及到上面步骤的转换命令:

#1..c->.iclang-E-ctest.c-otest.i#2..c->.bcclang-emit-llvmtest.c-c-otest.bc#3..c->.llclang-emit-llvmtest.c-S-otest.ll#4..i->.bcclang-emit-llvmtest.i-c-otest.bc#5..i->.llclang-emit-llvmtest.i-S-otest.ll#6..bc->.llllvm-distest.bc-otest.ll#7..ll->.bcllvm-astest.ll-otest.bc#8.多bc合并为一个bcllvm-linktest1.bctest2.bc-otest.bc

       上面列出了一部分Clang不同文件直接转换的命令(和第 1 部分的 示意图 序号匹配,还是只关心前端部分)。只是最后增加了一个将多个 bc 合并为一个 bc file 的命令。

3. 查看Clang AST结构

       我们可以通过如下的命令查看源码的AST结构:

clang-Xclang-ast-dump-ctest.c

       打印出来的AST信息,其实是预处理之后展开的源码信息,源码的AST内容在打印出来的内容的最下面。

       如下面的代码:

#include<stdio.h>intmain(){ printf("hello");return0;}

       打印出来的部分AST(仅根当前文件内容匹配部分)如下:

       头上的头文件引用等已经展开,没有了,但是下面的 main 函数定义,则如上面的 FunctionDecl 所示,并且给出了 代码中的位置。这里就不详细分析AST的结构了,写几个例子比对一下就很容易理解。

4. 编译正确性的影响因素

       当前,很多静态代码分析工具,都采用 Clang 和 LLVM 作为底座来开发静态代码分析工具。Clang自己也有 clang-tidy 工具可以用来做 C/C++ 语言的静态代码分析。为了能够用 Clang 和 LLVM 来成功分析 C/C++ 代码,需要考虑如何成功使用 Clang 和 LLVM 来编译 C/C++ 代码。可以考虑的是,成功生成 bc file,是静态代码分析的基础操作。

4.1 影响预处理结果的因素

       预处理过程,作用跟名字一样,都可以不当做编译的一个步骤,而是编译的一个预处理操作。我们说得再直白一点儿,其实就是做了一个文本替换的活儿,就是对 C/C++ 代码中的 预处理指令 进行处理。预处理指令很简单,比如 #include,#define 等,都是预处理指令(可以参考:/en-us/cpp/preprocessor/preprocessor-directives?view=msvc-,或者google下,很多介绍的)。

       如果程序中没有预处理指令,即使我们随便瞎写的代码,预处理也一般不会有问题,如下的代码(main.c):

abcdef

       我们仍然可以正确得到 预处理结果:

#1"main.c"#1"<built-in>"1#1"<built-in>"3#"<built-in>"3#1"<commandline>"1#1"<built-in>"2#1"main.c"2abcdef

       为了成功执行预处理执行,很容易理解,就是开奖走势分析源码可以对程序中的所有的 预处理指令 进行处理。比如:

       (1) #include,依赖了一个头文件,我们能不能成功找到这个头文件;

       (2) #define,定义了一个宏,在程序中定义宏的时候,我们能不能准确找到宏(找到,还必须准确);

       (3) 其他指令。

4.2 影响IR生成因素

       这一步是针对上一步生成的预处理指令,进行解析的操作。这一步才是最关键的,归根结底,我们需要保证一点:使Clang编译器可以正确识别出来代码中内容表示的语法结构,并且接纳这种语法结构!

       举一些简单例子:

       (1) -std 用来指定支持的 C/C++ 标准的,如果我们没有指定,那么就会采用 Clang 默认的标准来编译,就可能导致语法不兼容;

       (2) -Werror=* 等参数,可能将某些能识别的语法,给搞成错误的使用;

       (3) 其他的部分,跟语法识别的参数;

       (4) 还有一部分的语法,可能 Clang 自始至终就没有进行适配,这种就要考虑修改源码了。

4.3 链接相关因素

       在真正编译中,如果链接有问题,那就会失败,但是在静态代码分析中,链接有失败(无法链接)或者错误(不相关的给链接在一起),可能多点儿分析误报或者漏报,一般不会导致分析失败。这类问题,影响的不是中间表示的生成,而是分析结果(影响跨文件的过程间分析,影响对built-in函数的建模等)。

       一般,链接命令的捕获,target信息配置等,会影响这部分的能力。当然,也跟你实现的工具有关(如果实现的工具,就没有跨文件的能力,这部分内容也没啥影响)。

       作者:maijun。

什么是云服务

       云服务是基于互联网的相关服务的增加、使用和交付模式,通常涉及通过互联网来提供动态易扩展且经常是虚拟化的资源。云是网络、互联网的一种比喻说法。过去在图中往往用云来表示电信网,后来也用来表示互联网和底层基础设施的抽象。云服务指通过网络以按需、易扩展的方式获得所需服务。这种服务可以是阿里支付系统源码IT和软件、互联网相关,也可是其他服务。它意味着计算能力也可作为一种商品通过互联网进行流通。

       背景

       云计算是继年代大型计算机到客户端-服务器的大转变之后的又一种巨变。

       云计算(Cloud Computing)是分布式计算(Distributed Computing)、并行计算(Parallel Computing)、效用计算(Utility Computing)、网络存储(Network Storage Technologies)、虚拟化(Virtualization)、负载均衡(Load Balance)等传统计算机和网络技术发展融合的产物。

       2特点

       通过使计算分布在大量的分布式计算机上,而非本地计算机或远程服务器中,企业数据中心的运行将与互联网更相似。这使得企业能够将资源切换到需要的应用上,根据需求访问计算机和存储系统。

       好比是从古老的单台发电机模式转向了电厂集中供电的模式。它意味着计算能力也可以作为一种商品进行流通,就像煤气、水电一样,取用方便,费用低廉。最大的不同在于,它是通过互联网进行传输的。

       3形式

       IaaS:基础设施即服务

       IaaS(Infrastructure-as-a- Service):基础设施即服务。消费者通过Internet可以从完善的计算机基础设施获得服务。

       PaaS:平台即服务

       PaaS(Platform-as-a- Service):平台即服务。PaaS实际上是指将软件研发的平台作为一种服务,以SaaS的模式提交给用户。因此,PaaS也是SaaS模式的一种应用。但是,PaaS的出现可以加快SaaS的发展,尤其是加快SaaS应用的开发速度。

       SaaS:软件即服务

       SaaS(Software-as-a- Service):软件即服务。它是一种通过Internet提供软件的模式,用户无需购买软件,而是向提供商租用基于Web的软件,来管理企业经营活动。

       按需计算

       顾名思义,按需(on—demand)计算将计算机资源(处理能力、存储等)打包成类似公共设施的可计量的服务。在这一模式中,客户只需为他们所需的处理能力和存储支付费用。那些具有很大的需求高峰并伴有低得多的正常使用期的公司特别受益于效用计算。当然,该公司需要为高峰使用支付更多,但是,当高峰结束,正常使用模式恢复时,他们的费用会迅速下降。

       按需计算服务的客户端基本上将这些服务作为异地虚拟服务器来使用。无须投资自己的小刀自动收录源码物理基础设施,公司与云服务提供商之间执行现用现付的方案。

       按需计算本身并不是一个新概念,但它因云计算而获得新的生命。在过去的岁月里,按需计算由一台服务器通过某种分时方式而提供。

       4应用

       云物联

       “物联网就是物物相连的互联网”。这有两层意思:第一,物联网的核心和基础仍然是互联网,是在互联网基础上的延伸和扩展的网络;第二,其用户端延伸和扩展到了任何物品与物品之间,进行信息交换和通信。

       物联网的两种业务模式:

       1.MAI(M2M Application Integration), 内部MaaS;

       2.MaaS(M2M As A Service), MMO, Multi-Tenants(多租户模型)。

       随着物联网业务量的增加,对数据存储和计算量的需求将带来对“云计算”能力的要求:

       1.云计算:从计算中心到数据中心在物联网的初级阶段,PoP即可满足需求;

       2. 在物联网高级阶段,可能出现MVNO/MMO营运商(国外已存在多年),需要虚拟化云计算技术,SOA等技术的结合实现互联网的泛在服务:TaaS (everyTHING As A Service)。

       云安全

       云安全(Cloud Security)是一个从“云计算”演变而来的新名词。云安全的策略构想是:使用者越多,每个使用者就越安全,因为如此庞大的用户群,足以覆盖互联网的每个角落,只要某个网站被挂马或某个新木马病毒出现,就会立刻被截获。

       “云安全”通过网状的大量客户端对网络中软件行为的异常监测,获取互联网中木马、恶意程序的最新信息,推送到Server端进行自动分析和处理,再把病毒和木马的解决方案分发到每一个客户端。

       云存储

       云存储是在云计算(cloud computing)概念上延伸和发展出来的一个新的概念,是指通过集群应用、网格技术或分布式文件系统等功能,将网络中大量各种不同类型的存储设备通过应用软件集合起来协同工作,共同对外提供数据存储和业务访问功能的一个系统。 当云计算系统运算和处理的核心是大量数据的存储和管理时,云计算系统中就需要配置大量的存储设备,那么云计算系统就转变成为一个云存储系统,所以云存储是一个以数据存储和管理为核心的云计算系统。

       5优缺点

       优势

       云开发的优势之一就是规模经济。利用云计算供应商提供的基础设施,同在单一的企业内开发相比,开发者能够提供更好,更便宜和更可靠的应用。如果需要,应用能够利用云的全部资源而无须要求公司投资类似的物理资源。

       说到成本,由于云服务遵循一对多的模型,与单独的桌面程序部署相比,成本极大地降低了。云应用通常是“租用的”,以每用户为基础计价,而不是购买或许可软件程序(每个桌面一个)的物理拷贝。它更像是订阅模型而不是资产购买(和随之而来的贬值)模型,这意味着更少的前期投资和一个更可预知的月度业务费用流。

       部门喜欢云应用是因为所有的管理活动都经由一个中央位置而不是从单独的站点或工作站来管理。这使得员工能够通过Web来远程访问应用。其他的好处包括用需要的软件快速装备用户(称为“快速供应”),当更多的用户导致系统重负时添加更多计算资源(自动扩展)。当你需要更多的存储空间或带宽时,公司只需要从云中添加另外一个虚拟服务器。这比在自己的数据中心购买、安装和配置一个新的服务器容易得多。

       对开发者而言,升级一个云应用比传统的桌面软件更容易。只需要升级集中的应用程序,应用特征就能快速顺利地得到更新,而不必手工升级组织内每台台式机上的单独应用。有了云服务,一个改变就能影响运行应用的每一个用户,这大大降低了开发者的工作量。

       不足

       也许人们所意识到的云开发最大的不足就是给所有基于web的应用带来麻烦的问题:它安全吗?基于web的应用长时间以来就被认为具有潜在的安全风险。由于这一原因,许多公司宁愿将应用、数据和IT操作保持在自己的掌控之下。

       也就是说,利用云托管的应用和存储在少数情况下会产生数据丢失。尽管可以说,一个大的云托管公司可能比一般的企业有更好的数据安全和备份的工具。然而,在任何情况下,即便是感知到的来自关键数据和服务异地托管的安全威胁也可能阻止一些公司这么做。

       另外一个潜在的不足就是云计算宿主离线所导致的事件。尽管多数公司说这是不可能的,但它确实发生了,亚马逊的EC2业务在年2月日经受了一次大规模的服务中止,并抹去了一些客户应用数据。(该次业务中止由一个软件部署所引起,它错误地终止了数量未知的用户实例。)对那些需要可靠和安全平台的客户来说,平台故障和数据消失就像被粗鲁地唤醒一样。更进一步讲,如果一个公司依赖于第三方的云平台来存放数据而没有其他的物理备份,该数据可能处于危险之中。

       6评估

       云服务性能

       企业考虑云计算的关注点之一就是性能。实现应用程序在云中的高速交付是一个涉及多方面因素的挑战性命题,其中包括一个整体的接入方法和一个对应用程序“请求-响应”路径的端到端查看。

       性能问题包括:应用程序与数据相对于最终用户的地理位置,云中、云内外以及计算机层和数据存储多层次之间的I/O访问速度。当今,诸如CloudSleuth和CloudHarmony之类的众多服务研究报告试图通过从不同地理位置和采用不同应用程序的方法来度量和评估云计算供应商所提供服务的性能。

       云服务技术堆栈

       一直以来,一些云计算供应商都致力于提供特定软件堆栈的服务。通常,这就意味着他们从基础设施即服务(IaaS)转变至平台即服务(PaaS)。不同堆栈特定云可与其他的大多数流行软件堆栈相配合。

       其典型代表包括:Heroku和Engine Yard的Ruby;VMforce和Google应用程序引擎(GAE)的Java/Spring(其中GAE还支持Python);PHP Fog的PHP以及微软公司Windows Azure的.NET。

       如果你的应用程序使用以上堆栈之一进行构建,你可能需要考虑这些云计算平台。他们能够帮助你处理低层次基础设施的安装和配置工作,从而节省在时间和费用方面的巨大支出。另一方面,他们往往会要求开发商在进行架构和编写应用程序时遵循某些推荐的要求,以便于创建高等级的供应商级同步。

       云服务服务级别协议

       有些云供应商做出了提供更高等级服务的承诺,以示与其他行业竞争对手的不同。比如Rackspace提供更高等级云服务SLA,从而展开与云计算业内的巨头Amazon公司的竞争。

       请注意,SLA通常只是当服务发生故障时结果的一个指示,而不是实际服务的可靠性。其典型代表是GoGrid %确保的SLA。换而言之,GoGrid做出了%正常运行时间的承诺。如果它无法满足这一级别的可靠性,它将赔偿用户倍停机时所需支付的费用。

       虽然SLA是评估所有供应商承诺等级的一个有效指标,但了解特定云供应商的实际正常运行时间是一个更为棘手的难题。大多数供应商都提供了一个用于表明服务正常运行的状态页面,但是这些页面显示的数据通常只是数天前甚至更早时候的。为了获得实际具有可靠性和可用性的长期数据,用户最好依赖于客户反馈以及诸如CloudSleuth和CLoudHarmony的比较服务。

       云服务API:同步、社区以及生态系统

       选择合适云供应商的另外一个关键因素在于开放应用程序编程接口(API),它为访问基础设施和执行操作(例如配置服务器或解除服务器配置)提供外部调用方法。从很多方面来说,API都是重要的。

       首先,一个API可得到多个供应商同时支持,同时供应商也为用户提供了更大的功能扩展自由度。因为当从一个供应商转向另一个供应商,或同时与多个供应商合作时,基本上不用对应用程序做重大修改,所以显得更为容易。

       其次,API得到了社区开发人员的广泛支持,供应商可基于它构建一个具有配套服务和功能的完整生态系统。由Amazon web服务与应用(AWS)和Vmware云计算产品提供的API周围已形成庞大的生态系统,其中包括管理工具(如enStratus)、监控和管理工具(如Cloudkickh和RightScale)以及形成其完整云服务的其他服务。

       Vmware本身不提供云服务,但是不同的供应商使用Vmware的堆栈和API,特别是vCloud。例如Terremark和Savvis。

       Amazon公司和WMware公司以及Windows Azure都允许用户使用自己的堆栈和API实施内部云,从而使用户能够很容易地在混合云上管理和运行应用程序。所谓混合云是指由供应商托管,且在公司内部数据中心中运行的云。以Amazon公司为例,使用AWS启动通过Eucalyptus的API为私有云提供软件堆栈。

       业内的一个最新发展是Rackspace公司与美国航天局(NASA)合作,两者协同众多厂商和云供应商在其一个称为OpenStack的项目中对其软件堆栈公开了源代码。它最有可能被视为行业标准,因此此举将有助于创建一个有望替代Amazon和Vmware生态系统的实际可行标准。

       云服务安全性和法规遵从

       公司考虑实施据云计算的两大障碍依然是安全性与法规遵从。Zenoss公司在年第二季度进行的调查显示,接近%的受访者在被问及他们对云计算的最大关注问题时都选择了安全性。而紧随其后的选项是管理,它占受访者的.5%。Zenoss的调查结果与其他云计算相关调查的数字是一致的。

       而企业真正关注的问题并不是实际的安全威胁,而是他们无法遵守与安全相关的标准,如PCI。作为回应,当今许多云供应商都在吹嘘和炫耀他们所拥有的SAS- II型审计、安全白皮书和其他标准的证书。

       正在发展的云供应商Logicworks推出了具有法规遵从的云计算产品,即遵守一级PCI的云产品。

       云服务成本

       一个比较云供应商的简单直接方法似乎就是成本。问题在于考虑到客户实际使用的资源和支付的费用,在供应商中并不具备可比性。供应商提供虚拟机(VM)资源,但其内存容量、CPU时钟速度以及其他功能却各异。此外,实际提供给客户的部件也是虚拟的,这也造成难以对客户实际使用的资源进行度量以及其他同在云中客户如何影响这些资源。

       Amazon公司拥有EC2计算部门,Heroku向Dynos提交而其它厂商则创建自己的度量部门。度量评估不同云供应商成本和性能比的唯一真正可靠方法是使用相同的应用程序对多个供应商的服务进行试验,并比较运行结果。

       费用对比

       云计算的安全和管理问题是众所周知的,除此之外,关于云服务的计费也是一个不小的挑战。云服务供应商们总是喜欢吹嘘说他们的服务使用起来有多么的简单,实际上,广大IT经理们都已发现云计算服务的计费并不简单。

       云服务的计费是基于许多因素的,从所需的存储空间,到所使用的时间周期,再到每个月的流量分配,等等这些因素都可能成为计费参考。实际上还不止这些,一些云服务供应商还会基于SLA之内的一些隐性条款来收费。为了弄明白一项云计算服务的总费用,用户需要了解供应商账单上的每一项服务要素,以及其计费方式。

       服务的计费项目

       另一个决定服务真正费用的关键因素是所需的服务类型。对于一些企业而言,所谓的云服务可能只是服务器托管、专用服务器租赁,或是将应用运行在云中。而对于其它一些企业而言,云服务可能就是基于云的数据备份、业务持续性的维持,或是基本的存储托管。

       对于广大用户而言,要弄明白云计算服务最简单的方式就是将注意力放在最主要的服务项目上。大多数云服务供应商都会将它们的服务分为三个基本类型:云中服务器、云存储、云工作站和云应用。每一项服务都有其自己的计费方式。

       云中的服务器主要分为两种形式:虚拟服务器和物理服务器。换句话说,你既可以在虚拟服务器(与其他人共享物理硬件)上购买使用时间,也可以在专用服务器(你是该服务器唯一的租户)上购买使用时间。表1所示的就是云服务的计费方式:

       三大主流IaaS云服务计费方式对比

       整张实际上就是在对比不同云服务供应商的服务价格和计费方式。图中列出的每个供应商都会对一些额外的服务和功能征收额外的费用。此外,每项服务的价格也会随着协议长短、总的带宽需求或者所需存储规模的大小而有所变化。在许多情况下,用户是可以和供应商进行讨价还价的。

       不同的服务类型

       并不是说所有的云服务供应商都是一样的,如果你仔细观察一下供应商之间的区别以及他们各自处理用户需求的方式,就会发现这种差别是很明显的。为了给大家做一个对比,我们挑选了最为知名的三家云架构供应商:

       GoGrid将负载均衡服务放在其服务器产品当中,而且不收取额外的费用,此外,他们还免费提供GB的存储空间;

       Rackspace使用的是一种完全不同的计费机制,随着使用量的增长,他们会降低每十亿字节带宽的费用。此外,该公司还在一些虚拟服务器上提供免费的备份服务;

       Amazon的大多数服务随着使用量的增加都提供打折优惠,但是对于存储服务的启用和终止都会收取一定费用。

       如果你考虑一下最为简单的云存储服务概念,就会很明显地发现这几种计费方式及供应商业务的区别(图2)。再次强调一下,这张图只是对比不同供应商的计费方式。像其它云服务一样,云存储服务的价格也会受到协议时间长短、总的带宽需求或是说所需存储容量大小的影响。此外,这些服务的价格也有足够的讨价还价的空间。

       三大主流IaaS云服务计费方式对比

       对于使用其服务器托管服务的用户,GoGrid最初提供GB的免费存储空间,而且他们只为服务器托管用户提供云存储服务。独具特色的是,随着用户所购买的存储容量的增加,GoGrid的服务可以提供打折优惠。GoGrid的云存储服务是以一种定量的方式提供,目前为止还不提供用于启动或停止其它命令的Web服务应用程序接口。

       Rackspace试图让它的存储服务计费方式变得尽可能的简单化。他们对于云存储服务的采购提供按比例增减的模式,随着总量的增加,服务的单价也会有所下降。此外,如果文件的大小超过KB,他们不会收取存取费用。

       Amazon S3对于已删除数据不进行收费,根据所需存储总量的增加还会提供一定折扣。对于那些试图将价格稳定下来的公司,他们提供定价合同。对于一些规模较大的文件传输公司,他们建议使用其输入和输出服务,这样可以节省成本。

       理想地讲,云计算服务的计费模式应该和选择所需的存储功能和服务器计算资源没什么差别。而事实上,大多数IT经理都发现这种理想很难实现。他们必须仔细去考虑一些“隐性成本”,或是计费标准的变化,从而确定某项服务的真正费用。

       更大的挑战来自于一些“非技术”的因素,用户必须考虑到那些独立于谈判条款之外或是隐藏于SLA协议之中因素。

       解决这一问题的技巧就是用清晰而又精确的语言将每个合同期内每项服务的总费用写在纸上,这样才能明白真正的总预算金额。[1]

       7相关技术

       1、编程模式

       2、海量数据分布存储技术

       3、海量数据管理技术

       4、虚拟化技术

       5、云计算平台管理技术

       8相关问题

       数据隐私问题:如何保证存放在云服务提供商的数据隐私不被非法利用,不仅需要技术的改进,也需要法律的进一步完善

       数据安全性:有些数据是企业的商业机密没数据的安全性关系的企业的生存和发展。云计算数据的安全性问题解决不了会影响云计算在企业中的应用。

       用户的使用习惯:如何改变用户的使用习惯,使用户适应网络化的软硬件应用是长期而且艰巨的挑战。

       网络传输问题:云计算服务依赖网络,目前网速低切不稳定,使云应用的性能不高。云计算的普及依赖网络技术的发展。

       缺乏统一的技术标准:云计算的美好前景让传统IT厂商纷纷向云计算方向转型。但是由于缺乏统一的技术标准,尤其是接口标准,各厂商在开发各自产品和服务的过程中各自为政,这为将来不同服务之间的互连互通带来严峻挑战。

本文地址:http://04.net.cn/html/85a486795047.html 欢迎转发