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)前端
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> </dependency>
package com.jt.test; import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; 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.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.io.IOException; //@SpringBootTest //從spring容器中獲取bean對象,以後完成測試業務. public class TestHttpClient { /** * 1.實例化HttpClient對象 * 2.定義遠程訪問的url地址 * 3.定義請求類型的對象 * 4.發起http請求,獲取響應的結果 * 5.對返回值結果進行校驗.獲取真實的數據信息. * */ @Test public void testGet() throws IOException { HttpClient httpClient = HttpClients.createDefault(); String url = "http://www.baidu.com"; HttpGet httpGet = new HttpGet(url); HttpResponse httpResponse = httpClient.execute(httpGet); //常見結果狀態 200 404 406參數異常 500後端服務器異常 504超時 502訪問的網址不存在 //獲取狀態碼 int status = httpResponse.getStatusLine().getStatusCode(); if(status == 200){ //獲取響應結果 HttpEntity entity = httpResponse.getEntity(); String result = EntityUtils.toString(entity,"UTF-8"); System.out.println(result); } } }
用戶經過http://www.jt.com/user/testHt... 請求,獲取UserList集合信息.而且將其中的郵箱信息改成電話號碼.
JT-WEB服務器 訪問JT-SSO時的請求爲 http://sso/jt.com/user/testHt...java
@RequestMapping("/testHttpClient") @ResponseBody public List<User> testHttpClient(){ return userService.testHttpClient(); }
package com.jt.service; import com.jt.pojo.User; import com.jt.util.ObjectMapperUtil; 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.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import org.springframework.stereotype.Service; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; @Service public class UserServiceImpl implements UserService{ @Override public List<User> testHttpClient() { List userList = new ArrayList<>(); //由jt-web服務器去連接jt-sso的服務器 String url = "http://sso.jt.com/user/testHttpClient"; HttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(url); try { HttpResponse httpResponse =httpClient.execute(httpGet); if(httpResponse.getStatusLine().getStatusCode() == 200){ HttpEntity httpEntity = httpResponse.getEntity(); String result = EntityUtils.toString(httpEntity, "UTF-8"); userList = ObjectMapperUtil.toObject(result, userList.getClass()); /* for (LinkedHashMap<String,Object> map : userList){ User userTemp = new User(); userTemp.setId( Long.parseLong(map.get("id")+"")); userTemp.setUsername((String)map.get("username")); userTemp.setPassword((String)map.get("password")); userTemp.setPhone((String)map.get("phone")); userTemp.setEmail((String)map.get("phone")); userList2.add(userTemp); }*/ } } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } return userList; } }
/** * http://sso.jt.com/user/testHttpClient * 返回List<User> */ @RequestMapping("testHttpClient") public List<User> testHttpClient(){ return userService.findAll(); }
@Override public List<User> findAll() { return userMapper.selectList(null); }
面向服務的架構(SOA)是一個組件模型,它將應用程序的不一樣功能單元(稱爲服務)進行拆分,並經過這些服務之間定義良好的接口和協議聯繫起來。接口是採用中立的方式進行定義的,它應該獨立於實現服務的硬件平臺、操做系統和編程語言。這使得構建在各類各樣的系統中的服務能夠以一種統一和通用的方式進行交互。nginx
RPC(Remote Procedure Call)遠程過程調用,簡單的理解是一個節點請求另外一個節點提供的服務
本地過程調用:若是須要將本地student對象的age+1,能夠實現一個addAge()方法,將student對象傳入,對年齡進行更新以後返回便可,本地方法調用的函數體經過函數指針來指定。
遠程過程調用:addAge方法在其餘的服務器中,若是須要調用則必須經過遠程的方式通知其餘服務器幫我完成業務調用.web
總結: 利用第三方的服務器,幫我完成業務調用的過程.
理解: 分佈式環境中 業務調用幾乎都是RPC的.算法
說明:spring
說明:因爲nginx負載均衡/反向代理都須要人爲的配置,而且出現了問題不能及時的實現故障的遷移,因此須要升級爲微服務的架構的設計.apache
實現步驟:
1.服務提供者啓動時,將本身的信息註冊到註冊中心中.
2.註冊中心接受到了用戶的請求以後,更新服務器列表信息.
3.當消費者啓動時,首先會鏈接註冊中心,獲取服務列表數據.
4.註冊中心將本身的服務列表信息同步給客戶端(消費者).
5.消費者接收到服務列表數據以後,將信息保存到本身的本地.方便下次調用.
6.當消費者接收到用戶的請求時,根據本身服務列表的信息進行負載均衡的操做,選擇其中一個服務的提供者,根據IP:PORT 進行RPC調用.
7.當服務提供者宕機時,註冊中心會有心跳檢測機制,若是檢查宕機,則更新本地的服務列表數據,而且全網廣播通知全部的編程
公式: 存活的節點>N/2
例子:後端
1個節點可否搭建集羣? 1-1 > 1/2 假的 1個節點不能搭建集羣 2各節點可否搭建集羣? 2-1 > 2/2 假的 2個節點不能搭建集羣 3個節點可否搭建集羣? 3-1 > 3/2 真的 3個節點能搭建集羣 4個節點可否搭建集羣? 4-1 > 4/2 真的 4個節點能搭建集羣 3個節點最多容許宕機1臺,不然集羣崩潰. 4個節點最多容許宕機1臺,不然集羣崩潰.
搭建奇數臺和偶數臺其實均可以,可是從容災性的角度考慮,發現奇數和偶數的效果相同,因此搭建奇數臺.api
說明:zk集羣選舉採用最大值(myid)優先的算法實現,若是集羣中沒有主機,則開始選舉(超半數便可),若是有主機,則選舉結束.
考題: 1 2 3 4 5 6 7 依次啓動時
問題1:誰當主機? 4當主機
問題2:誰永遠不能當選主機? 1,2,3
提供了六大核心能力:面向接口代理的高性能RPC調用,智能容錯和負載均衡,服務自動註冊和發現,高度可擴展能力,運行期流量調度,可視化的服務治理與運維。
調用原理圖:
1).修改SpringBoot的版本
2).修改模塊名稱 改成dubbo-jt-demo-interface