1. HttpClient
1.1 业务需求说明
1.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)
1.3 HttpClient入门案例
1.3.1 导入jar包
<!--添加httpClient jar包 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
1.3.2 HttpClient入门案例
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);
}
}
}
1.4 HttpClient实现业务逻辑
1.4.1 业务需求
用户通过http://www.jt.com/user/testHttpClient请求,获取UserList集合信息.
JT-WEB服务器 访问JT-SSO时的请求http://sso.jt.com/user/testHttpClient
1.4.2 编辑前端Controller
@RequestMapping("/testHttpClient")
@ResponseBody
public List<User> testHttpClient(){
return userService.testHttpClient();
}
1.4.2 编辑前端Service
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;
}
}
1.4.3 编辑后端Controller
/**
* http://sso.jt.com/user/testHttpClient
* 返回List<User>
*/
@RequestMapping("testHttpClient")
public List<User> testHttpClient(){
return userService.findAll();
}
1.4.4 编辑后端Service
@Override
public List<User> findAll() {
return userMapper.selectList(null);
}
2. SOA思想
2.1 SOA思想介绍
面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
3. RPC介绍(调用形式的统称)
3.1 RPC介绍
RPC(Remote Procedure Call)远程过程调用,简单的理解是一个节点请求另一个节点提供的服务
本地过程调用:如果需要将本地student对象的age+1,可以实现一个addAge()方法,将student对象传入,对年龄进行更新之后返回即可,本地方法调用的函数体通过函数指针来指定。
远程过程调用:addAge方法在其他的服务器中,如果需要调用则必须通过远程的方式通知其他服务器帮我完成业务调用.
总结: 利用第三方的服务器,帮我完成业务调用的过程.
理解: 分布式环境中 业务调用几乎都是RPC的.
4. 微服务
4.1 什么是微服务
说明:
1. 为了降低代码的耦合性,将项目进行了拆分.按照功能模块拆分为若干个项目.该项目称之为服务.(分布式思想).
2. 如果采用微服务的结构,要求服务器如果出现了故障应该实现自动化的故障的迁移(高可用HA)
4.2 现有服务分析
说明:由于nginx负载均衡/反向代理都需要人为的配置,并且出现了问题不能及时的实现故障的迁移,所以需要升级为微服务的架构的设计.
4.3 微服务架构设计
实现步骤:
1. 服务提供者启动时,.将自己的信息注册到注册中心中.
2. 注册中心接受到了用户的请求之后,更新服务列表信息.
3. 当消费者启动时,首先会链接注册中心,获取服务列表数据.
4. 注册中心将自己的服务列表信息同步给客户端(消费者)
5. 消费者接收到服务列表数据之后,将信息保存到自己的本地.方便下次调用
6. 当消费者接收到用户的请求时,根据自己服务列表的信息进行负载均衡的操作,选择其中一个服务的提供者,根据IP:PORT 进行RPC调用.
7. 当服务提供者宕机时,注册中心会有心跳检测机制,如果检查宕机,则更新本地的服务列表数据,并且全网广播通知所有的消费者更新服务列表.
4.4 ZK安装参见文档
4.5 为什么集群一般都是奇数个?
公式: 存活的节点 > N/2
常识: 最小的集群的单位3台.
例子:
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台,否则集群崩溃.
搭建奇数台和偶数台其实都可以,但是从容灾性的角度考虑,发现奇数和偶数的效果相同,.所以搭建奇数台.
4.6 ZK集群选举规则
说明: zk集群选举采用最大值(myid)优先的算法实现,如果集群中没有主机,则开始选举(超半数即可),如果有主机,则选举结束.
考题: 1 2 3 4 5 6 7 依次启动时
问题1:谁当主机? 4当主机
问题2:谁永远不能当选主机? 1,2,3
5 Dubbo框架
5.1 Dubbo介绍
Apache Dubbo |ˈdʌbəʊ| 提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。
调用原理图:
5.2 Dubbo入门案例
5.2.1 修改配置文件内容
1).修改SpringBoot的版本
2).修改模块名称 改为dubbo-jt-demo-interface
5.2.2 导入maven项目
6.总结
本节主要是解决跨域不安全的问题,使用HttpClient实现业务,以及微服务的应用。