1. 程式人生 > >SpringCloud--01、微服務簡介

SpringCloud--01、微服務簡介

一、微服務

1、集中式架構

當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。此時,
用於簡化增刪改查工作量的資料訪問框架(ORM)是影響專案開發的關鍵

存在的問題:

- 程式碼耦合,開發維護困難
- 無法針對不同模組進行鍼對性優化
- 無法水平擴充套件
- 單點容錯率低,併發能力差

2、垂直拆分

訪問量大、為了提高更高的併發和業務需求、根據業務功能對系統進行拆分

優點:

- 系統拆分實現了流量分擔,解決了併發問題
- 可以針對不同模組進行優化
- 方便水平擴充套件,負載均衡,容錯率提高

缺點:

系統間相互獨立,會有很多重複開發工作,影響開發效率

3、分散式服務

抽取核心業務、作為獨立服務、此時,用於提高業務複用及整合的分散式呼叫是關鍵。

優點:

將基礎服務進行了抽取,系統間相互呼叫,提高了程式碼複用和開發效率

缺點:

系統間耦合度變高,呼叫關係錯綜複雜,難以維護

4、服務治理(SOA)

SOA:面向服務的架構

服務越來越多,此時需增加一個排程中心基於訪問壓力實時管理叢集容量,提高叢集利用率。
此時,用於提高機器利用率的資源排程和治理中心(SOA)是關鍵。

缺點:

- 服務間會有依賴關係,一旦某個環節出錯會影響較大
- 服務關係複雜,運維、測試部署困難,不符合DevOps思想

5、微服務

概述

微服務架構,就是將單一程式開發成多個微服務,每個微服務執行處理唯一的業務,
並使用輕量級機制通訊,通常是HTTP RPC。這些服務圍繞業務能力來劃分構建的,並通過完全自動化部署機制來
獨立部署。這些服務可以使用不同的程式語言,以及不同資料儲存技術,以保證最低限度的集中式管理

 二、遠端呼叫方式(通訊方式)

無論是微服務還是SOA,都面臨著服務間的遠端呼叫。那麼服務間的通訊方式:RPC 、HTTP

1、RPC

RPC:Remote Procedure Call遠端過程呼叫,類似的還有RMI。
自定義資料格式,基於原生TCP通訊,速度快,效率高。早期的webservice,現在熱門的dubbo,都是RPC的典型

2、Http

http其實是一種網路傳輸協議,基於TCP,規定了資料傳輸的格式。
現在客戶端瀏覽器與服務端通訊基本都是採用Http協議。也可以用來進行遠端服務呼叫。缺點是訊息封裝臃腫。
現在熱門的Rest風格,就可以通過http協議來實現。
- 優點:RPC方式更加透明,對使用者更方便。Http方式更靈活,沒有規定API和語言,跨語言、跨平臺
- 缺點:RPC方式需要在API層面進行封裝,限制了開發的語言環境。

三、HTTP客戶端工具

HttpClient、OKHttp、URLConnection

1、HttpClient

HttpClient是Apache公司的產品,是Http Components下的一個元件。

特點:

- 基於標準、純淨的Java語言。實現了Http1.0和Http1.1
- 以可擴充套件的面向物件的結構實現了Http全部的方法(GET, POST, PUT, DELETE, HEAD, OPTIONS, and TRACE)
- 支援HTTPS協議。
- 通過Http代理建立透明的連線。
- 自動處理Set-Cookie中的Cookie。

Rest風格:

- 查詢:GET,/user/12
- 新增:POST, /user
- 修改:PUT, /user
- 刪除:DELTE, /user/12

發起get請求

  @Test
    public void testGet() throws IOException {
        HttpGet request = new HttpGet("http://www.baidu.com");
        String response = this.httpClient.execute(request, new BasicResponseHandler());
        System.out.println(response);
    }

發起Post請求:

@Test
public void testPost() throws IOException {
    HttpPost request = new HttpPost("http://www.baidu.com/");
    request.setHeader("User-Agent",
                      "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
    String response = this.httpClient.execute(request, new BasicResponseHandler());
    System.out.println(response);
}

也可以訪問http://localhost/user/3

UserController.java

package com.baidus.user.contrlooer;

import com.baidus.user.pojo.User;
import com.baidus.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ Author     :ShaoWei Sun.
 * @ Date       :Created in 15:54 2018/12/1
 */
@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User queryById(@PathVariable("id") Long id){
        return userService.queryById(id);
    }
}

測試

    @Test
    public void testGetPojo() throws IOException {
        HttpGet request = new HttpGet("http://localhost:8081/user/1");
        String response = this.httpClient.execute(request, new BasicResponseHandler());
        System.out.println(response);
    }

2、Spring的RestTemplate <低層為URLConnection>new RestTemplate(Okhttp)

Spring提供了一個RestTemplate模板工具類,對基於Http的客戶端進行了封裝,
並且實現了物件與json的序列化和反序列化,非常方便。RestTemplate並沒有限定Http的客戶端型別,
而是進行了抽象,目前常用的3種都有支援:

- HttpClient
- OkHttp
- JDK原生的URLConnection(預設的)

在專案中注入RestTemplate

@SpringBootApplication
public class HttpDemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(HttpDemoApplication.class, args);
	}

	@Bean
	public RestTemplate restTemplate() {
        // 預設的RestTemplate,底層是走JDK的URLConnection方式。
        //return new RestTemplate(new OkHttp3ClientHttpRequestFactory())
        //寫了OkHttp就是OkHttp
		return new RestTemplate();
	}
}
通過RestTemplate的getForObject()方法,傳遞url地址及實體類的位元組碼,
RestTemplate會自動發起請求,接收響應,並且幫我們對響應結果進行反序列化。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = HttpDemoApplication.class)
public class HttpDemoApplicationTests {

	@Autowired
	private RestTemplate restTemplate;

	@Test
	public void httpGet() {
		User user = this.restTemplate.getForObject("http://localhost/hello/2", User.class);
		System.out.println(user);
	}
}