当后端服务器执行出错时, 会执行全局异样的解决. 然而 JSONP 的申请的调用要求 返回值类型 callback(JSON)构造, 所以须要重构全局异样解决的返回值构造类型.
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());
}
}
}
Http 协定可能是当初 Interent 上应用最多 最重要的协定了. 越来也多的 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).
<!-- 增加 httpClient jar 包 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
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);
}
}
}
用户通过网址 http://www.jt.com/getItems 要求采纳 httpClient 形式, 获取 jt-manage 中的商品信息 之后 json 串的模式展示.jt-web 服务器拜访 jt-manage 时的网址 http://manage.jt.com/getItems.
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();
}
}
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;
}
}
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();
}
}
@Override
public List<Item> getItems() {return itemMapper.selectList(null);
}
面向服务的架构 (SOA)是一个组件模型, 它将应用程序的不同性能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协定分割起来。接口是采纳中立的形式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的零碎中的服务能够以一种对立和通用的形式进行交互。
RPC 是 近程过程调用(Remote Procedure Call)的缩写模式。
1. 当实现业务时本人没有方法间接实现时, 须要通过第三方帮忙能力实现的业务.
2. 应用 RPC 时 ” 感觉 ” 上就是在调用本人的办法实现业务.
1. 如果采纳 nginx 形式实现负载平衡, 当服务数量扭转时, 都必须手动的批改 nginx.conf 配置文件. 不够智能.
2. 所有的申请都会通过 nginx 服务器作为直达. 如果 nginx 服务器一旦宕, 则间接影响整个零碎.nginx 最好只做简略的反向代理即可.
传统形式不够智能
1. 将服务信息写入到注册核心(1. 服务名称 2. 服务 IP 地址 3. 端口)
2. 注册核心接管到服务器信息会动静保护服务列表数据.
3. 消费者启动时会链接注册核心, 目标是获取服务列表数据.
4. 注册核心会将服务列表数据同步给消费者, 并且保留到消费者本地, 当前不便调用.
5. 当消费者开始业务调用时, 会依据已知的服务信息进行负载平衡操作, 拜访服务提供者.
6. 当服务提供者宕机时, 因为注册核心有心跳检测机制, 所以会动静保护服务列表.
7. 当注册核心的服务列表变动时, 则会全网进行播送, 告诉所有消费者更新本地服务列表.
ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 Hbase 的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的性能包含:配置保护、域名服务、分布式同步、组服务等。
ZooKeeper 的指标就是封装好简单易出错的要害服务,将简略易用的接口和性能高效、性能稳固的零碎提供给用户。
ZooKeeper 蕴含一个简略的原语集,提供 Java 和 C 的接口。
ZooKeeper 代码版本中,提供了分布式独享锁、选举、队列的接口,代码在 $zookeeper_homesrcrecipes。其中散布锁和队列有 Java 和 C 两个版本,选举只有 Java 版本。
概括:ZK 次要的工作是 服务的调度, 提供一致性性能.
公式:存活节点的数量 > N/2集群能够创立
1 台: 1-1<1/2 不能创立
2 台: 2-1=2/2 不能创立
3 台: 3-1>3/2 能够创立
4 台: 4-1>4/2 能够创立
准则:myid 最大值优先 myid 值越大的越容易入选主机 超半数批准即入选主机.
题目: 问 1,2,3,4,5,6,7 顺次启动 问谁能入选主机 谁永远入选不了主机?
当投票进行到 4 时,4 得票过半 入选主机.
因为 1,2,3 的得票永远不可能超过半数 所以 1,2,3 永远入选不了主机.