1.JSONP全局異常處理機制
1.1 問題説明
當後端服務器執行出錯時,會執行全局異常的處理.但是JSONP的請求的調用要求 返回值類型 callback(JSON)結構.所以需要重構全局異常處理的返回值結構類型.
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 業務需求
業務説明:當做某些操作時,可能會對數據進行業務加工,之後由服務器與服務器之間形同通訊.
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)
總結: 在java代理內部可以使用httpClient發起http請求訪問服務器獲取資源.(工具API)
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.
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 頁面效果展現
- SOA思想(微服務代理編輯的標準)
=====================
面向服務的架構(SOA)是一個組件模型,它將應用程序的不同功能單元(稱為服務)進行拆分,並通過這些服務之間定義良好的接口和協議聯繫起來。接口是採用中立的方式進行定義的,它應該獨立於實現服務的硬件平台、操作系統和編程語言。這使得構建在各種各樣的系統中的服務可以以一種統一和通用的方式進行交互。
- RPC思想介紹
===========
RPC是遠程過程調用(Remote Procedure Call)的縮寫形式。
總結:
- 當完成業務時自己沒有辦法直接完成時,需要通過第三方幫助才能完成的業務.
- 使用RPC時"感覺"上就是在調用自己的方法完成業務.
5.微服務思想
核心: 1.分佈式思想(拆) 2.自動化(HA,自動化)
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 為什麼集羣一般都是奇數
- 3台集羣最多宕機幾台 集羣可以正常工作 最多宕機1台
- 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…