綜合使用spring cloud技術實現微服務應用


  • cloud-config-server:配置服務器
  • cloud-eureka-server:eureka注冊服務器
  • cloud-simple-service:一個使用mybatis的數據庫應用,服務端
  • cloud-simple-ui:webui客戶端

  我們先來看看如何實現webui客戶端。在spring boot中,已經不推薦使用jsp,所以你如果使用jsp來實現webui端,將會很麻煩。這可能跟現在的開發主流偏重移動端有關,跟微服務有關,跟整個時代當前的技術需求有關。單純以html來作為客戶端,有很多好處,比如更利於使用高速緩存;使后台服務無狀態話,更利於處理高並發;更利於頁面作為服務,小服務組合成大服務等。

  我們首選來創建webui應用,參考git cloud-simple-ui工程:

   

         這個應用包括前端html頁面,還包括一個后台controller淺層。這是一個前端應用,為什么要包括controller淺層?這是因為這個controller淺層是用來做服務組合的,因為一個頁面可能涉及到調用多個服務,而這些服務又有可能涉及事務和並發問題,所以還是需要靠java來完成。當然,也可以單獨編寫一個api gateway來實現這一層,可以使用go、node.js語言等,也可以使用java/netty(主流還是java,因為開發部署效率高)。

       Controller層的WebApplication就是這個應用的入口,代碼如下:

  @SpringBootApplication

  @EnableEurekaClient

  @EnableHystrix

  public class WebApplication {

         public static void main(String[] args) throws Exception {

               SpringApplication.run(WebApplication.class, args);

    }

  }

  這些注解大都在前面提到過用法:

  @SpringBootApplication相當於@Configuration、@EnableAutoConfiguration、@ComponentScan三個注解合用。

  @EnableEurekaClient配置本應用將使用服務注冊和服務發現,注意:注冊和發現用這一個注解。

  @EnableHystrix表示啟用斷路器,斷路器依賴於服務注冊和發現。

  Controller層的service包封裝了服務接口訪問,UserService類代碼如下:

  @Service

  public class UserService {

          @Autowired

    RestTemplate restTemplate; 

    final String SERVICE_NAME="cloud-simple-service";        

     @HystrixCommand(fallbackMethod = "fallbackSearchAll")

    public List<User> searchAll() {

      return restTemplate.getForObject("http://"+SERVICE_NAME+"/user", List.class);

    }   

    private List<User> fallbackSearchAll() {

               System.out.println("HystrixCommand fallbackMethod handle!");

               List<User> ls = new ArrayList<User>();

               User user = new User();

               user.setUsername("TestHystrix");

               ls.add(user);

               return ls;

    }

  }

  這里使用了斷路器,就是@HystrixCommand注解。斷路器的基本作用就是@HystrixCommand注解的方法失敗后,系統將自動切換到fallbackMethod方法執行。斷路器Hystrix具備回退機制、請求緩存和請求打包以及監控和配置等功能,在這里我們只是使用了它的核心功能:回退機制,使用該功能允許你快速失敗並迅速恢復或者回退並優雅降級。

  這里使用restTemplate進行服務調用,因為使用了服務注冊和發現,所以我們只需要傳入服務名稱SERVICE_NAME作為url的根路徑,如此restTemplate就會去EurekaServer查找服務名稱所代表的服務並調用。而這個服務名稱就是在服務提供端cloud-simple-service中spring.application.name所配置的名字,這個名字在服務啟動時連同它的IP和端口號都注冊到了EurekaServer。

  封裝好服務調用后,你只需要在Controller類里面注入這個服務即可:

  @RestController

  public class UserController {       

       @Autowired

       UserService userService;      

       @RequestMapping(value="/users")

       public ResponseEntity<List<User>> readUserInfo(){

              List<User> users=userService.searchAll();         

              return new ResponseEntity<List<User>>(users,HttpStatus.OK);

       }

  }

  至此這個webui應用的java端就開發完了,我們再來看頁面模塊。

  可以看到,頁面文件都放在resources\static目錄下面,這是spring boot默認的頁面文件主文件夾,你如果在里面放一個index.html,那么直接訪問根路徑http://localhost:8080/會直接定位到這個頁面。所以這個static就相當於傳統web項目里面的webapp文件夾。

  在這里包括兩個頁面index.html和user-page.html,用戶訪問首頁時將會加載user-page.html子頁面。

  首頁index.html頁面核心代碼如下:

  <html ng-app="users">

  <head>   

    <script src="js/app.js"></script>

  </head>

  <body>

  <div ng-view class="container">

  </div>

  </body>

  </html>

  頁面user-page.html代碼如下:

  <div>

  <ul ng-controller="userCtr">

    <li ng-repeat="item in userList">

  {{item.username}}   

  </li>

  </ul>

  </div>

  app.js頁面代碼如下:

  angular.module('users', ['ngRoute']).config(function ($routeProvider) {

  $routeProvider.when('/', {

        templateUrl: 'user-page.html',

        controller: 'userCtr'

  })

  }).controller('userCtr', function ($scope, $http) {

  $http.get('users').success(function (data) {

           //alert(data+"");

        $scope.userList = data;

  });

  });

  這里使用了angularJS庫。Angular可以綁定模型數據到頁面變量,在user-page.html看到的{{item.username}}就是它的綁定語法,這個語法根jsp或freemarker這些模板技術都類似,只不過Angular是用在客戶端的,而前者是用在服務端的。

  至此這個webui應用就開發完了,改一下配置文件和pom文件就可以運行了。配置文件包括配置管理服務器地址,注冊服務器地址等,在bootstrap.properties文件中:

  spring.cloud.config.uri=http://127.0.0.1:${config.port:8888}

  spring.cloud.config.name=cloud-config

  spring.cloud.config.profile=${config.profile:dev}

  eureka.client.serviceUrl.defaultZone=http\://localhost\:8761/eureka/

  spring.application.name=simple-ui-phone

  這些配置我們在上一章已經提到過了,這里不再解釋。因為使用了斷路器,所以相比上一章的cloud-simple-service項目,需要加入hystrix依賴,只有一個starter依賴:

  <dependency>

    <groupId>org.springframework.cloud</groupId>

  <artifactId>spring-cloud-starter-hystrix</artifactId>

  </dependency>

  Spring把事情做的如此簡單,不管是服務注冊還是斷路器,連同注解加配置文件再加上依賴總共不超過十行代碼。如此簡單就可以使用一個分布式應用,也難怪國內外業內人員都高度重視這個框架,在簡單和速度就是硬道理的今天,這個框架有着重要的意義。

   剩下最重要的事情就是進行部署了,我們以此使用命令啟動這些服務及應用:

  1)  java -jar cloud-config-server-0.0.1.jar,啟動配置服務器,固定綁定端口8888;

  2)  java -jar cloud-eureka-server-1.0.0.jar,啟動注冊服務器,固定綁定端口8671;

  3)  java -jar cloud-simple-service-1.0.0.jar --server.port=8081 >log8081.log,啟動后台服務,綁定端口8081

  4)  java -jar cloud-simple-service-1.0.0.jar --server.port=8082 >log8082.log,啟動后台服務,綁定端口8082

  5)  java -jar cloud-simple-ui-1.0.0.jar --server.port=8080 >log8080.log,啟動前端ui應用,綁定端口8080

  運行http://localhost:8080/即可看到運行的結果。其中“>log8080.log”表示輸出日志到文件。

  這里運行了兩個cloud-simple-service實例,主要是為了演示ribbon負載均衡。默認情況下使用ribbon不需要再作任何配置,不過它依賴於注冊服務器。當然也可以對ribbon進行一些自定義設置,比如配置它的超時時間、重試次數等。啟用了負載均衡后,當我們關掉前端頁面上次指向的服務時(從日志中看),比如我們刷新頁面看到它調用的是8081服務,那么我們關掉這個服務。關掉后再刷新會發現執行了斷路器,過幾秒再刷新,它已經切換到了8082這台服務器,這說明負載均衡起作用了。

 
分類:  spring cloud


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM