DatacenterBroker.java文件如下:
(其中,相关语句已经做好标注)
1 /* 2 * Title: CloudSim Toolkit 3 * Description: CloudSim (Cloud Simulation) Toolkit for Modeling and Simulation of Clouds 4 * Licence: GPL - http://www.gnu.org/copyleft/gpl.html 5 * 6 * Copyright (c) 2009-2010, The University of Melbourne, Australia 7 */ 8 package org.cloudbus.cloudsim; 9 10 import java.util.ArrayList;//Resizable-array implementation of the List interface 11 import java.util.HashMap;//散列表要解决的一个问题就是散列值的冲突问题,通常是两种方法:链表法和开放地址法。链表法就是将相同hash值的对象组织成一个链表放在hash值对应的槽位 (来源:http://www.yuloo.com/news/1012/527961.html) 12 import java.util.LinkedList;//The class implements the Deque interface, providing first-in-first-out queue operations for add, poll, along with other stack and deque operations 13 import java.util.List;//An ordered collection (also known as a sequence) 14 import java.util.Map;//An object that maps keys to values 15 16 import org.cloudbus.cloudsim.core.CloudSim;//This class extends the CloudSimCore to enable network simulation in CloudSim 17 import org.cloudbus.cloudsim.core.CloudSimTags;//Contains various static command tags that indicate a type of action that needs to be undertaken by CloudSim entities when they receive or send events 18 import org.cloudbus.cloudsim.core.SimEntity;//This class represents a simulation entity 19 import org.cloudbus.cloudsim.core.SimEvent;//This class represents a simulation event which is passed between the entities in the simulation 20 import org.cloudbus.cloudsim.lists.CloudletList;//CloudletList is a collection of operations on lists of Cloudlets 21 import org.cloudbus.cloudsim.lists.VmList;//VmList is a collection of operations on lists of VMs 22 23 /**DatacentreBroker类代表一经纪人行使用户角色,隐藏了虚拟机管理,如虚拟机创建,用户任务提交和虚拟机销毁 24 * DatacentreBroker represents a broker 25 * acting on behalf of a user. It hides VM management, 26 * as vm creation, sumbission of cloudlets to this VMs 27 * and destruction of VMs. 28 * 29 * @author Rodrigo N. Calheiros 30 * @author Anton Beloglazov 31 * @since CloudSim Toolkit 1.0 32 */ 33 public class DatacenterBroker extends SimEntity { 34 35 // TODO: remove unnecessary variables移除不必要的变量 36 37 /** The vm list. 虚拟机列表*/ 38 private List<? extends Vm> vmList; 39 40 /** The vms created list. 虚拟机创建列表*/ 41 private List<? extends Vm> vmsCreatedList; 42 43 /** The cloudlet list.云任务列表 */ 44 private List<? extends Cloudlet> cloudletList; 45 46 /** The cloudlet submitted list. 云任务提交列表*/ 47 private List<? extends Cloudlet> cloudletSubmittedList; 48 49 /** The cloudlet received list. 云任务接收列表*/ 50 private List<? extends Cloudlet> cloudletReceivedList; 51 52 /** The cloudlets submitted. 提交的云任务*/ 53 private int cloudletsSubmitted; 54 55 /** The vms requested. 请求的虚拟机*/ 56 private int vmsRequested; 57 58 /** The vms acks.虚拟机确认 */ 59 private int vmsAcks; 60 61 /** The vms destroyed.虚拟机销毁 */ 62 private int vmsDestroyed; 63 64 /** The datacenter ids list. 数据中心ID列表*/ 65 private List<Integer> datacenterIdsList; 66 67 /** The datacenter requested ids list.请求数据中心ID列表 */ 68 private List<Integer> datacenterRequestedIdsList; 69 70 /** The vms to datacenters map. 虚拟机到数据中心映射*/ 71 private Map<Integer, Integer> vmsToDatacentersMap; 72 73 /** The datacenter characteristics list. 数据中心特征列表*/ 74 private Map<Integer, DatacenterCharacteristics> datacenterCharacteristicsList; 75 76 77 /**【创建新的数据中心代理对象】 78 * Created a new DatacenterBroker object. 79 * 80 * @param name name to be associated with this entity (as 81 * required by Sim_entity class from simjava package) 82 * 83 * @throws Exception the exception 84 * 85 * @pre name != null 86 * @post $none 87 */ 88 public DatacenterBroker(String name) throws Exception { 89 super(name); 90 91 setVmList(new ArrayList<Vm>()); 92 setVmsCreatedList(new ArrayList<Vm>()); 93 setCloudletList(new ArrayList<Cloudlet>()); 94 setCloudletSubmittedList(new ArrayList<Cloudlet>()); 95 setCloudletReceivedList(new ArrayList<Cloudlet>()); 96 97 cloudletsSubmitted=0;//= 与(0)是什么区别 98 setVmsRequested(0); 99 setVmsAcks(0); 100 setVmsDestroyed(0); 101 102 setDatacenterIdsList(new LinkedList<Integer>()); 103 setDatacenterRequestedIdsList(new ArrayList<Integer>()); 104 setVmsToDatacentersMap(new HashMap<Integer, Integer>()); 105 setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>()); 106 } 107 108 /**【方法 : 发送给代理必须创建的虚拟机列表】 109 * This method is used to send to the broker the list with 110 * virtual machines that must be created. 111 * 112 * @param list the list 113 * 114 * @pre list !=null 115 * @post $none 116 */ 117 public void submitVmList(List<? extends Vm> list) { 118 getVmList().addAll(list); 119 } 120 121 /**【方法 : 发送云任务列表给代理】 122 * This method is used to send to the broker the list of 123 * cloudlets. 124 * 125 * @param list the list 126 * 127 * @pre list !=null 128 * @post $none 129 */ 130 public void submitCloudletList(List<? extends Cloudlet> list){ 131 getCloudletList().addAll(list); 132 } 133 134 /**(绑定云任务到指定虚拟机) 135 * Specifies that a given cloudlet must run in a specific virtual machine. 136 * 137 * @param cloudletId ID of the cloudlet being bount to a vm 138 * @param vmId the vm id 139 * 140 * @pre cloudletId > 0 141 * @pre id > 0 142 * @post $none 143 */ 144 public void bindCloudletToVm(int cloudletId, int vmId){ 145 CloudletList.getById(getCloudletList(), cloudletId).setVmId(vmId); 146 } 147 148 /**处理可用于代理的事件 149 * Processes events available for this Broker. 150 * 151 * @param ev a SimEvent object 152 * 153 * @pre ev != null 154 * @post $none 155 */ 156 @Override//http://www.javaeye.com/wiki/topic/694939 参考注释 157 public void processEvent(SimEvent ev) {//implements org.cloudbus.cloudsim.core.SimEntity.processEvent 158 //Log.printLine(CloudSim.clock()+"[Broker]: event received:"+ev.getTag()); 159 switch (ev.getTag()){ 160 // Resource characteristics request资源特征请求 161 case CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST: 162 processResourceCharacteristicsRequest(ev); 163 break; 164 // Resource characteristics answer资源特征应答 165 case CloudSimTags.RESOURCE_CHARACTERISTICS: 166 processResourceCharacteristics(ev); 167 break; 168 // VM Creation answer 虚拟机创建应答 169 case CloudSimTags.VM_CREATE_ACK: 170 processVmCreate(ev); 171 break; 172 //A finished cloudlet returned 返回一个完成的云任务 173 case CloudSimTags.CLOUDLET_RETURN: 174 processCloudletReturn(ev); 175 break; 176 // if the simulation finishes 仿真完成 177 case CloudSimTags.END_OF_SIMULATION: 178 shutdownEntity(); 179 break; 180 // other unknown tags are processed by this method 处理unknown tags 181 default: 182 processOtherEvent(ev); 183 break; 184 } 185 } 186 187 /** 188 * Process the return of a request for the characteristics of a PowerDatacenter(功率意识数据中心). 189 * 190 * @param ev a SimEvent object 191 * 192 * @pre ev != $null 193 * @post $none 194 */ 195 protected void processResourceCharacteristics(SimEvent ev) { 196 DatacenterCharacteristics characteristics = (DatacenterCharacteristics) ev.getData(); 197 getDatacenterCharacteristicsList().put(characteristics.getId(), characteristics); 198 199 if (getDatacenterCharacteristicsList().size() == getDatacenterIdsList().size()) { 200 setDatacenterRequestedIdsList(new ArrayList<Integer>()); 201 createVmsInDatacenter(getDatacenterIdsList().get(0)); 202 } 203 } 204 205 /**处理PowerDatacenter特征的请求 206 * Process a request for the characteristics of a PowerDatacenter. 207 * 208 * @param ev a SimEvent object 209 * 210 * @pre ev != $null 211 * @post $none 212 */ 213 protected void processResourceCharacteristicsRequest(SimEvent ev) { 214 setDatacenterIdsList(CloudSim.getCloudResourceList()); 215 setDatacenterCharacteristicsList(new HashMap<Integer, DatacenterCharacteristics>()); 216 217 Log.printLine(CloudSim.clock()+": "+getName()+ ": Cloud Resource List received with "+getDatacenterIdsList().size()+" resource(s)"); 218 219 for (Integer datacenterId : getDatacenterIdsList()) { 220 sendNow(datacenterId, CloudSimTags.RESOURCE_CHARACTERISTICS, getId()); 221 } 222 } 223 224 /**【请求虚拟机响应应答】 225 * Process the ack received due to a request for VM creation. 226 * 227 * @param ev a SimEvent object 228 * 229 * @pre ev != null 230 * @post $none 231 */ 232 protected void processVmCreate(SimEvent ev) { 233 int[] data = (int[]) ev.getData(); 234 int datacenterId = data[0]; 235 int vmId = data[1]; 236 int result = data[2]; 237 238 if (result == CloudSimTags.TRUE) { 239 getVmsToDatacentersMap().put(vmId, datacenterId); 240 getVmsCreatedList().add(VmList.getById(getVmList(), vmId)); 241 Log.printLine(CloudSim.clock()+": "+getName()+ ": VM #"+vmId+" has been created in Datacenter #" + datacenterId + ", Host #" + VmList.getById(getVmsCreatedList(), vmId).getHost().getId()); 242 } else { 243 Log.printLine(CloudSim.clock()+": "+getName()+ ": Creation of VM #"+vmId+" failed in Datacenter #" + datacenterId); 244 } 245 246 incrementVmsAcks(); 247 248 if (getVmsCreatedList().size() == getVmList().size() - getVmsDestroyed()) { // all the requested VMs have been created 所有请求虚拟机已创建 249 submitCloudlets(); 250 } else { 251 if (getVmsRequested() == getVmsAcks()) { // all the acks received, but some VMs were not created所有响应接受。但一些虚拟机没有创建 252 // find id of the next datacenter that has not been tried找出下一个数据中心ID 253 for (int nextDatacenterId : getDatacenterIdsList()) { 254 if (!getDatacenterRequestedIdsList().contains(nextDatacenterId)) { 255 createVmsInDatacenter(nextDatacenterId); 256 return; 257 } 258 } 259 260 //all datacenters already queried 咨询了所有的数据中心 261 if (getVmsCreatedList().size() > 0) { //if some vm were created 一些虚拟机已经创建 262 submitCloudlets(); 263 } else { //no vms created. abort停止 264 Log.printLine(CloudSim.clock() + ": " + getName() + ": none of the required VMs could be created. Aborting"); 265 finishExecution(); 266 } 267 } 268 } 269 } 270 271 /**【处理云任务返回事件】 272 * Process a cloudlet return event. 273 * 274 * @param ev a SimEvent object 275 * 276 * @pre ev != $null 277 * @post $none 278 */ 279 protected void processCloudletReturn(SimEvent ev) { 280 Cloudlet cloudlet = (Cloudlet) ev.getData(); 281 getCloudletReceivedList().add(cloudlet); 282 Log.printLine(CloudSim.clock()+": "+getName()+ ": Cloudlet "+cloudlet.getCloudletId()+" received"); 283 cloudletsSubmitted--; 284 if (getCloudletList().size()==0&&cloudletsSubmitted==0) { //all cloudlets executed 所有云任务已执行完 285 Log.printLine(CloudSim.clock()+": "+getName()+ ": All Cloudlets executed. Finishing..."); 286 clearDatacenters(); 287 finishExecution(); 288 } else { //some cloudlets haven't finished yet 一些任务没完成 289 if (getCloudletList().size()>0 && cloudletsSubmitted==0) { 290 //all the cloudlets sent finished. It means that some bount 291 //cloudlet is waiting its VM be created云任务发送完毕 292 clearDatacenters(); 293 createVmsInDatacenter(0); 294 } 295 296 } 297 } 298 299 300 301 302 303 304 305 /**【重写 创建一个新的不同类型的代理】 306 * Overrides this method when making a new and different type of Broker. 307 * This method is called by {@link #body()} for incoming unknown tags. 308 * 309 * @param ev a SimEvent object 310 * 311 * @pre ev != null 312 * @post $none 313 */ 314 protected void processOtherEvent(SimEvent ev){ 315 if (ev == null){ 316 Log.printLine(getName() + ".processOtherEvent(): " + "Error - an event is null."); 317 return; 318 } 319 320 Log.printLine(getName() + ".processOtherEvent(): " + "Error - event unknown by this DatacenterBroker."); 321 } 322 323 /**在数据中心里创建虚拟机 324 * Create the virtual machines in a datacenter. 325 * 326 * @param datacenterId Id of the chosen PowerDatacenter 327 * 328 * @pre $none 329 * @post $none 330 */ 331 protected void createVmsInDatacenter(int datacenterId) { 332 // send as much vms as possible for this datacenter before trying the next one 333 int requestedVms = 0; 334 String datacenterName = CloudSim.getEntityName(datacenterId); 335 for (Vm vm : getVmList()) { 336 if (!getVmsToDatacentersMap().containsKey(vm.getId())) { 337 Log.printLine(CloudSim.clock() + ": " + getName() + ": Trying to Create VM #" + vm.getId() + " in " + datacenterName); 338 sendNow(datacenterId, CloudSimTags.VM_CREATE_ACK, vm); 339 requestedVms++; 340 } 341 } 342 343 getDatacenterRequestedIdsList().add(datacenterId); 344 345 setVmsRequested(requestedVms); 346 setVmsAcks(0); 347 } 348 349 /**提交云任务到虚拟机 350 * Submit cloudlets to the created VMs. 351 * 352 * @pre $none 353 * @post $none 354 */ 355 protected void submitCloudlets() { 356 int vmIndex = 0; 357 for (Cloudlet cloudlet : getCloudletList()) { 358 Vm vm; 359 if (cloudlet.getVmId() == -1) { //if user didn't bind this cloudlet and it has not been executed yet用户没有绑定云任务 360 vm = getVmsCreatedList().get(vmIndex); 361 } else { //submit to the specific vm提交给专门的虚拟机 362 vm = VmList.getById(getVmList(), cloudlet.getVmId()); 363 if (vm == null) { // vm was not created 虚拟机没有创建 364 Log.printLine(CloudSim.clock()+": "+getName()+ ": Postponing execution of cloudlet "+cloudlet.getCloudletId()+": bount VM not available"); 365 continue; 366 } 367 } 368 369 Log.printLine(CloudSim.clock()+": "+getName()+ ": Sending cloudlet "+cloudlet.getCloudletId()+" to VM #"+vm.getId()); 370 cloudlet.setVmId(vm.getId()); 371 sendNow(getVmsToDatacentersMap().get(vm.getId()), CloudSimTags.CLOUDLET_SUBMIT, cloudlet); 372 cloudletsSubmitted++; 373 vmIndex = (vmIndex + 1) % getVmsCreatedList().size(); 374 getCloudletSubmittedList().add(cloudlet); 375 } 376 377 //从等待列表中除去提交的任务 remove submitted cloudlets from waiting list 378 for (Cloudlet cloudlet : getCloudletSubmittedList()) { 379 getCloudletList().remove(cloudlet); 380 } 381 } 382 383 /**销毁虚拟机 384 * Destroy the virtual machines running in datacenters. 385 * 386 * @pre $none 387 * @post $none 388 */ 389 protected void clearDatacenters() { 390 for (Vm vm : getVmsCreatedList()) { 391 Log.printLine(CloudSim.clock() + ": " + getName() + ": Destroying VM #" + vm.getId()); 392 sendNow(getVmsToDatacentersMap().get(vm.getId()), CloudSimTags.VM_DESTROY, vm); 393 } 394 395 getVmsCreatedList().clear(); 396 } 397 398 /**仿真结束 399 * Send an internal event communicating the end of the simulation. 400 * 401 * @pre $none 402 * @post $none 403 */ 404 private void finishExecution() { 405 sendNow(getId(), CloudSimTags.END_OF_SIMULATION); 406 } 407 408 /* (non-Javadoc) 409 * @see cloudsim.core.SimEntity#shutdownEntity() 410 */ 411 @Override 412 public void shutdownEntity() { 413 Log.printLine(getName() + " is shutting down..."); 414 } 415 416 /* (non-Javadoc) 417 * @see cloudsim.core.SimEntity#startEntity() 418 */ 419 @Override 420 public void startEntity() { 421 Log.printLine(getName() + " is starting..."); 422 schedule(getId(), 0, CloudSimTags.RESOURCE_CHARACTERISTICS_REQUEST); 423 } 424 425 /**虚拟机列表 426 * Gets the vm list. 427 * 428 * @param <T> the generic type 429 * @return the vm list 430 */ 431 @SuppressWarnings("unchecked") 432 public <T extends Vm> List<T> getVmList() { 433 return (List<T>) vmList; 434 } 435 436 /**设置虚拟机列表 437 * Sets the vm list. 438 * 439 * @param <T> the generic type 440 * @param vmList the new vm list 441 */ 442 protected <T extends Vm> void setVmList(List<T> vmList) { 443 this.vmList = vmList; 444 } 445 446 447 /**云任务列表 448 * Gets the cloudlet list. 449 * 450 * @param <T> the generic type 451 * @return the cloudlet list 452 */ 453 @SuppressWarnings("unchecked") 454 public <T extends Cloudlet> List<T> getCloudletList() { 455 return (List<T>) cloudletList; 456 } 457 458 459 /**设置云任务列表 460 * Sets the cloudlet list. 461 * 462 * @param <T> the generic type 463 * @param cloudletList the new cloudlet list 464 */ 465 protected <T extends Cloudlet> void setCloudletList(List<T> cloudletList) { 466 this.cloudletList = cloudletList; 467 } 468 469 /**云任务提交列表 470 * Gets the cloudlet submitted list. 471 * 472 * @param <T> the generic type 473 * @return the cloudlet submitted list 474 */ 475 @SuppressWarnings("unchecked") 476 public <T extends Cloudlet> List<T> getCloudletSubmittedList() { 477 return (List<T>) cloudletSubmittedList; 478 } 479 480 481 /**设置云任务提交列表 482 * Sets the cloudlet submitted list. 483 * 484 * @param <T> the generic type 485 * @param cloudletSubmittedList the new cloudlet submitted list 486 */ 487 protected <T extends Cloudlet> void setCloudletSubmittedList(List<T> cloudletSubmittedList) { 488 this.cloudletSubmittedList = cloudletSubmittedList; 489 } 490 491 /**云任务接收列表 492 * Gets the cloudlet received list. 493 * 494 * @param <T> the generic type 495 * @return the cloudlet received list 496 */ 497 @SuppressWarnings("unchecked") 498 public <T extends Cloudlet> List<T> getCloudletReceivedList() { 499 return (List<T>) cloudletReceivedList; 500 } 501 502 /**设置云任务接收列表 503 * Sets the cloudlet received list. 504 * 505 * @param <T> the generic type 506 * @param cloudletReceivedList the new cloudlet received list 507 */ 508 protected <T extends Cloudlet> void setCloudletReceivedList(List<T> cloudletReceivedList) { 509 this.cloudletReceivedList = cloudletReceivedList; 510 } 511 512 /**虚拟机列表 ??? 513 * Gets the vm list. 514 * 515 * @param <T> the generic type 516 * @return the vm list 517 */ 518 @SuppressWarnings("unchecked") 519 public <T extends Vm> List<T> getVmsCreatedList() { 520 return (List<T>) vmsCreatedList; 521 } 522 523 /** 524 * Sets the vm list. 525 * 526 * @param <T> the generic type 527 * @param vmsCreatedList the vms created list 528 */ 529 protected <T extends Vm> void setVmsCreatedList(List<T> vmsCreatedList) { 530 this.vmsCreatedList = vmsCreatedList; 531 } 532 533 /**虚拟机请求 534 * Gets the vms requested. 535 * 536 * @return the vms requested 537 */ 538 protected int getVmsRequested() { 539 return vmsRequested; 540 } 541 542 /** 543 * Sets the vms requested. 544 * 545 * @param vmsRequested the new vms requested 546 */ 547 protected void setVmsRequested(int vmsRequested) { 548 this.vmsRequested = vmsRequested; 549 } 550 551 /**虚拟机响应 552 * Gets the vms acks. 553 * 554 * @return the vms acks 555 */ 556 protected int getVmsAcks() { 557 return vmsAcks; 558 } 559 560 /** 561 * Sets the vms acks. 562 * 563 * @param vmsAcks the new vms acks 564 */ 565 protected void setVmsAcks(int vmsAcks) { 566 this.vmsAcks = vmsAcks; 567 } 568 569 /**增加虚拟机响应 570 * Increment vms acks. 571 */ 572 protected void incrementVmsAcks() { 573 this.vmsAcks++; 574 } 575 576 /**销毁虚拟机 577 * Gets the vms destroyed. 578 * 579 * @return the vms destroyed 580 */ 581 protected int getVmsDestroyed() { 582 return vmsDestroyed; 583 } 584 585 /** 586 * Sets the vms destroyed. 587 * 588 * @param vmsDestroyed the new vms destroyed 589 */ 590 protected void setVmsDestroyed(int vmsDestroyed) { 591 this.vmsDestroyed = vmsDestroyed; 592 } 593 594 /**数据执行ID 595 * Gets the datacenter ids list. 596 * 597 * @return the datacenter ids list 598 */ 599 protected List<Integer> getDatacenterIdsList() { 600 return datacenterIdsList; 601 } 602 603 /** 604 * Sets the datacenter ids list. 605 * 606 * @param datacenterIdsList the new datacenter ids list 607 */ 608 protected void setDatacenterIdsList(List<Integer> datacenterIdsList) { 609 this.datacenterIdsList = datacenterIdsList; 610 } 611 612 /**虚拟机到数据中心映射 613 * Gets the vms to datacenters map. 614 * 615 * @return the vms to datacenters map 616 */ 617 protected Map<Integer, Integer> getVmsToDatacentersMap() { 618 return vmsToDatacentersMap; 619 } 620 621 /** 622 * Sets the vms to datacenters map. 623 * 624 * @param vmsToDatacentersMap the vms to datacenters map 625 */ 626 protected void setVmsToDatacentersMap(Map<Integer, Integer> vmsToDatacentersMap) { 627 this.vmsToDatacentersMap = vmsToDatacentersMap; 628 } 629 630 /**数据中心特征列表 631 * Gets the datacenter characteristics list. 632 * 633 * @return the datacenter characteristics list 634 */ 635 protected Map<Integer, DatacenterCharacteristics> getDatacenterCharacteristicsList() { 636 return datacenterCharacteristicsList; 637 } 638 639 /** 640 * Sets the datacenter characteristics list. 641 * 642 * @param datacenterCharacteristicsList the datacenter characteristics list 643 */ 644 protected void setDatacenterCharacteristicsList(Map<Integer, DatacenterCharacteristics> datacenterCharacteristicsList) { 645 this.datacenterCharacteristicsList = datacenterCharacteristicsList; 646 } 647 648 /** 649 * Gets the datacenter requested ids list. 650 * 651 * @return the datacenter requested ids list 652 */ 653 protected List<Integer> getDatacenterRequestedIdsList() { 654 return datacenterRequestedIdsList; 655 } 656 657 /** 658 * Sets the datacenter requested ids list. 659 * 660 * @param datacenterRequestedIdsList the new datacenter requested ids list 661 */ 662 protected void setDatacenterRequestedIdsList(List<Integer> datacenterRequestedIdsList) { 663 this.datacenterRequestedIdsList = datacenterRequestedIdsList; 664 } 665 666 }