第三階段 Day17 JSONP全局異常處理機制 HttpClient SOA思想 RPC調用 Zookeeper Dubbo

1.JSONP全局異常處理機制

1.1 問題說明

當後端服務器執行出錯時,會執行全局異常的處理.可是JSONP的請求的調用要求 返回值類型 callback(JSON)結構.因此須要重構全局異常處理的返回值結構類型.
在這裏插入圖片描述java

1.2 編輯全局異常處理機制

`package com.jt.aop;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.vo.SysResult;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;

//@ControllerAdvice  //攔截controller層
//@ResponseBody
@RestControllerAdvice   //定義全局異常的處理類   AOP=異常通知
public class SystemAOP {

    /**
     *  定義全局異常的方法  當遇到了什麼異常時,程序開始執行   參數通常class類型
     *  若是一旦發生異常,則應該輸出異常的信息,以後返回錯誤數據便可.
     *
     *  解決跨域全局異常處理的規則: 京淘項目的跨域都是使用JSONP.   http://xxxx?callback=xxxxx
     *  若是請求中攜帶了callback參數 則認爲是JSONP跨域請求.
     *  難點: 如何獲取callback參數呢??/
     */
    @ExceptionHandler({RuntimeException.class})
    public Object systemAop(Exception e, HttpServletRequest request){
        e.printStackTrace();
        String callback  = request.getParameter("callback");
        if(StringUtils.isEmpty(callback)){
            //常規方法調用方式
            return SysResult.fail();
        }else{
            //證實是jsonp跨域請求
            return new JSONPObject(callback, SysResult.fail());
        }
    }
}`

2.HttpClient

2.1 業務需求

業務說明:當作某些操做時,可能會對數據進行業務加工,以後由服務器與服務器之間形同通信.
在這裏插入圖片描述
在這裏插入圖片描述nginx

2.2 HttpClient介紹

HTTP 協議多是如今 Internet 上使用得最多、最重要的協議了,愈來愈多的 Java 應用程序須要直接經過 HTTP 協議來訪問網絡資源。雖然在 JDK 的 java net包中已經提供了訪問 HTTP 協議的基本功能,可是對於大部分應用程序來講,JDK 庫自己提供的功能還不夠豐富和靈活。HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,而且它支持 HTTP 協議最新的版本和建議。HttpClient 已經應用在不少的項目中,好比 Apache Jakarta 上很著名的另外兩個開源項目 Cactus 和 HTMLUnit 都使用了 HttpClient。如今HttpClient最新版本爲 HttpClient 4.5 .6(2015-09-11)web

總結: 在java代理內部可使用httpClient發起http請求訪問服務器獲取資源.(工具API)spring

2.3 HttpClient入門案例

2.3.1 引入jar包

`<!--添加httpClient jar包 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>`

2.3.2 編輯測試API

`package com.jt;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.junit.jupiter.api.Test;

import java.io.IOException;

public class HttpClientTest {

    /**
     * 要求:在java代碼內部,獲取百度的頁面.
     * 實現步驟:
     *  1.肯定目標地址: https://www.baidu.com/
     *  2.建立httpClient客戶端對象
     *  3.建立請求類型
     *  4.發起http請求.而且獲取響應的結果.以後判斷狀態碼是否爲200 若是等於200則請求正確
     *  5.若是請求正確則動態獲取響應值信息.以後進行數據的再次加工....
     *  */
    @Test
    public void testGet() throws IOException {
        String url = "https://www.jd.com/";
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        HttpResponse httpResponse = httpClient.execute(httpGet);
        if(httpResponse.getStatusLine().getStatusCode() == 200) {
            //表示用戶請求正確
            //獲取返回值數據
            HttpEntity httpEntity = httpResponse.getEntity();
            String result = EntityUtils.toString(httpEntity, "UTF-8");
            System.out.println(result);
        }
    }
}`

2.4 HttpClient增強案例

2.4.1 案例要求

用戶經過網址 http://www.jt.com/getItems 要求採用httpClient方式,獲取jt-manage中的商品信息 以後json串的形式展示.
jt-web服務器訪問jt-manage時的網址 http://manage.jt.com/getItems.sql

2.4.2 編輯前臺 HttpClientController

`package com.jt.controller;

import com.jt.pojo.Item;
import com.jt.service.HttpClientService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class HttpClientController {

    @Autowired
    private HttpClientService httpClientService;
    /**
     * 獲取後端manage中的商品數據信息
     */
    @RequestMapping("/getItems")
    public List<Item> getItems(){

        return httpClientService.getItems();
    }
}`

2.4.2 編輯前臺 HttpClientService

`package com.jt.service;

import com.jt.pojo.Item;
import com.jt.util.ObjectMapperUtil;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class HttpClientServiceImpl implements HttpClientService{

    @Override
    public List<Item> getItems() {
        List<Item> itemList = new ArrayList<>();
        //1.定義遠程訪問網址
        String url = "http://manage.jt.com/getItems";
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
           HttpResponse httpResponse = httpClient.execute(httpGet);
           if(httpResponse.getStatusLine().getStatusCode() == 200){
               String result =
                       EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
               //result是jt-manage爲jt-web返回的List<Item>的JSON串
               if(!StringUtils.isEmpty(result)){
                   itemList = ObjectMapperUtil.toObj(result, itemList.getClass());
               }
           }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        return itemList;
    }
}`

2.4.3 編輯後臺 HttpClientController

`package com.jt.web.controller;

import com.jt.pojo.Item;
import com.jt.service.ItemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class HttpClientController {

    @Autowired
    private ItemService itemService;

    /**
     * url請求地址: http://manage.jt.com/getItems
     */
    @RequestMapping("/getItems")
    public List<Item> getItems(){

        return itemService.getItems();
    }

 }`

2.4.4 編輯後臺 HttpClientService

`@Override
    public List<Item> getItems() {

        return itemMapper.selectList(null);
    }`

2.4.5 頁面效果展示

在這裏插入圖片描述

  1. SOA思想(微服務代理編輯的標準)

=====================apache

面向服務的架構(SOA)是一個組件模型,它將應用程序的不一樣功能單元(稱爲服務)進行拆分,並經過這些服務之間定義良好的接口和協議聯繫起來。接口是採用中立的方式進行定義的,它應該獨立於實現服務的硬件平臺、操做系統和編程語言。這使得構建在各類各樣的系統中的服務能夠以一種統一和通用的方式進行交互。編程

在這裏插入圖片描述

  1. RPC思想介紹

===========json

RPC是遠程過程調用(Remote Procedure Call)的縮寫形式。
總結:後端

  1. 當完成業務時本身沒有辦法直接完成時,須要經過第三方幫助才能完成的業務.
  2. 使用RPC時"感受"上就是在調用本身的方法完成業務.

5.微服務思想

核心: 1.分佈式思想(拆) 2.自動化(HA,自動化)api

5.1 傳統項目問題

1.若是採用nginx方式 實現負載均衡,當服務數量改變時,都必須手動的修改nginx.conf配置文件.不夠智能.
2.全部的請求都會經過nginx服務器做爲中轉.若是nginx服務器一旦宕機,則直接影響整個系統.nginx最好只作簡單的反向代理便可
傳統的方式 不夠智能…

在這裏插入圖片描述

5.2 微服務調用方式介紹

在這裏插入圖片描述
調用步驟:
1.將服務信息寫入到註冊中心(1.服務名稱 2.服務IP地址 3.端口)
2.註冊中心接收到服務器信息,會動態的維護服務列表數據.
3.消費者啓動時會連接註冊中心.目的獲取服務列表數據.
4.註冊中心會將服務列表數據同步給消費者,而且保存到消費者本地.之後方便調用.
5.當消費者開始業務調用時,會根據已知的服務信息進行負載均衡操做,訪問服務提供者.
6.當服務提供者宕機時,由與註冊中心有心跳檢測機制.因此會動態的維護服務列表.
7.當註冊中心的服務列表變化時, 則會全網廣播 通知全部的消費者 更新本地服務列表.

5.3 Zookeeper 註冊中心介紹

ZooKeeper是一個分佈式的,開放源碼的分佈式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個爲分佈式應用提供一致性服務的軟件,提供的功能包括:配置維護、域名服務、分佈式同步、組服務等。
ZooKeeper的目標就是封裝好複雜易出錯的關鍵服務,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。
ZooKeeper包含一個簡單的原語集,提供Java和C的接口。
ZooKeeper代碼版本中,提供了分佈式獨享鎖、選舉、隊列的接口,代碼在$zookeeper_homesrcrecipes。其中分佈鎖和隊列有Java和C兩個版本,選舉只有Java版本。
歸納: ZK主要的任務是服務的調度,提供一致性的功能.

5.4 關於集羣知識介紹

5.4.1 最小的集羣單位幾臺

公式: 存活節點的數量 > N/2 集羣能夠建立
1臺: 1-1 > 1/2 假的
2臺: 2-1> 2/2 假的
3臺: 3-1> 3/2 正確
4臺: 4-1> 4/2 正確

結論: 搭建集羣的最小單位3臺.

5.4.2 爲何集羣通常都是奇數

  1. 3臺集羣最多宕機幾臺 集羣能夠正常工做 最多宕機1臺
  2. 4臺集羣最多宕機幾臺集羣能夠正常工做 最多宕機1臺
    若是實現相同的功能 奇數臺更優.

5.5 關於zk集羣選舉規則

原則: myid最大值優先 myid值越大的越容易當主機. 超半數贊成即當選主機
題目: 問1,2,3,4,5,6,7依次啓動 問1:誰當主機 4當主機
問2:誰永遠不能當選主機??? 1 2 3

6 做業

預習Dubbo框架
修改代碼:
修改入門案例的dubbo項目的pom.xml文件
在這裏插入圖片描述

`1.項目版本`

在這裏插入圖片描述
2.修改module標籤
在這裏插入圖片描述
3.導入項目
將dubbo-jt項目粘貼到工做空間 和jt平級 以後右鍵 add Maven…
在這裏插入圖片描述

相關文章
相關標籤/搜索