京淘实训Day16-跨域-dubbo
1.面试题
1.1 问题1
问题:redis集群中最多可以存储16384个数据?
答案: 不对 分区只是告知数据它属于哪个分区,至于分区内部可以存储多少的数据由redis内存空间决定.
分区结果1 = crc16(key1)%16384 = 3000
分区结果1 = crc16(key2)%16384 = 3000
1.2 问题2
问题: Redis集群中最多部署多少台主机??
答案: Redis集群最多可以支持16384个主机. 每台主机一个槽位.
1.3 问题3
问题: Redis可以将数据保存到内存中,如果有多个客户端同时操作同一个key,问是否有线程并发问题???
答案: 不会 因为redis在执行过程中是单进程单线程操作, 串行的操作.
1.4 简述搜索引擎的工作原理
倒排索引: 根据关键字,检索文章的位置
1.5 搜索引擎为什么只记录静态页面
因为动态页面可能导致搜索的结果与真实的信息不符.出现问题. 并且搜索引擎规定.页面只能是html静态页面.
2.跨域(二)
2.1 实现jt-sso的反向代理
2.1.1 业务说明
要求通过jt-sso 访问http://localhost:8093服务器.
2.1.2 编辑nginx 配置文件
#配置jt-sso服务器
server {
listen 80;
server_name sso.jt.com;
location / {
proxy_pass http://localhost:8093;
}
}
修改完成之后,重启nginx服务器
2.2 cors跨域
2.2.1 CORS介绍
CORS是当下主流的一种跨域的访问形式,当下几乎所有的主流的浏览器其实都可以进行跨域的访问.浏览器在发起跨域的访问时新增一个请求头信息,来标识跨域访问.
浏览器自动拼接请求头,之后实现了跨域的访问.
2.2.2 配置服务端
说明:由于前端浏览器添加了请求头,标识该请求是一个跨域请求.但是同时需要告知后端服务器,接收请求时,需要识别跨域的请求头信息.
/**
* 如果后端服务器需要进行跨域的访问,则需要开启跨域的配置
* @author LYJ
*
*/
@Configuration //标识配置类
public class WebMVCConfig implements WebMvcConfigurer{
//sso.jt.com
//新增跨域访问
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //请求拦截的路径 所有的请求路径
.allowedOrigins("*") //* 不限定请求的服务器信息
.allowedMethods("GET", "POST", "DELETE", "PUT", "OPTIONS","HEAD") //请求类型
.allowCredentials(true) //是否允许携带cookie
.maxAge(3600); //校验请求的有效期
//跨域刚开始时需要试探性的访问一次 是否允许跨域!!!
}
}
2.2.3 编辑Ajax请求
alert("发起第二个请求")
$.ajax({
url:"http://sso.jt.com/findCors",
type:"get", //jsonp只能支持get请求
success:function (data){ //data经过jQuery封装返回就是json串
console.log(data);
}
});
3.用户数据校验
3.1业务说明
当用户添加用户名时,需要与后端服务器进行数据的校验.如果后端数据库中已经存在该用户信息.则提示该用户已存在. 如果数据库没有该数据,则提示用户名可以使用.
3.1如何实现
关键问题: 客户端服务器: www.jt.com
后端服务器: sso.jt.com
2台服务器之间应该如何通信???
远程服务器通信方式:
1. httpClient 步骤繁琐.
2. cors 跨域访问
3. jsonp跨域访问
3.2 用户注册页面分析
1).说明:通过F12开发者工具进行监控,发现该请求采用jsonp的形式进行跨域.
2.查询页面JS的位置
3).ajax js写法
3.3 用户数据校验的业务接口
3.4 编辑jt-sso的UserController
说明:由于前端的跨域请求,所有需要在后端编辑Controller即可
package com.jt.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.jt.pojo.User;
import com.jt.service.UserService;
import com.jt.util.ObjectMapperUtil;
import com.jt.vo.SysResult;
//是否需要跳转页面 true:@Controller false:@RestController
@RestController
//@CrossOrigin(origins="http://www.jt.com") //只对当前controller有效
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 目的: 校验用户信息是否存在
* url地址: http://sso.jt.com/user/check/{param}/{type}
* 参数: param type参数类型
* 返回值: SysResult对象
* 标识符: true 表示用户已存在
* false 表示用户不存在 可以使用
*
* JSONP
* 1.回调函数名称
* 2.特殊格式处理
*/
@RequestMapping("/check/{param}/{type}")
public JSONPObject checkUser(@PathVariable String param,
@PathVariable int type,
String callback) {
//根据用户传递的参数,判断数据库中是否有数据.
boolean flag = userService.checkUser(param,type);
SysResult sysResult = SysResult.success(flag);
return new JSONPObject(callback, sysResult);
}
}
3.5 编辑jt-sso的UserService
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
/**
* type=1/2/3 1 username、2 phone、3 email 将123转化为数据库字段
* 1.如何查询数据库!!!
* 2.判断依据? 根据用户信息查询总记录数 >0 已存在 ==0 可以使用
* 3.返回值结果与业务关系 true 已存在 false 可以使用
*/
@Override
public boolean checkUser(String param, Integer type) {
//1.将type转化为具体的字段信息
Map<Integer,String> map = new HashMap<>();
map.put(1, "username");
map.put(2, "phone");
map.put(3, "email");
//2.根据用户的类型获取字段信息
String column = map.get(type);
QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
queryWrapper.eq(column, param);
Integer count = userMapper.selectCount(queryWrapper);
//3.根据结果返回数据
return count>0?true:false;
}
}
3.6 页面效果展现
4. Dubbo框架
4.1 使用框架的目的
1.以一种统一的方式实现前后端的调用.
2.要求业务调用实现高可用机制.
3.实现服务的自动的发现功能.
上述业务系统的弊端
1). 业务服务之间进行访问时,都会经过nginx服务器.造成nignx服务器负载压力高.
2).nginx服务器没办法实现服务器的高可用.只能做到当访问的服务器宕机时,nginx会访问下一台服务器.保证服务的正常的运行.(没有高可用)
3).如果服务器数量发生了变化.则需要手动的修改nginx的配置文件 这样的方式不够便捷.
4.2 服务器端服务的自动功能的实现----注册中心(微服务)
目的: 能否自动的实现服务的注册和发现.当服务开启之后无需编辑任何的配置文件.程序就可以正常的调用.如果后端的服务器发生了宕机的现象.用户也无需干预.可以自动的实现服务的剔除.
步骤:
1.当服务生产者启动时,会将自己的服务信息写入注册中心.
2.注册中心接收生产者的信息之后,自己维护了服务列表信息.
3.当服务消费者启动时,会链接注册中心获取服务列表
4.注册中心将自己维护的服务列表信息同步给消费者,并且让消费者在本地缓存起来,方便以后调用.
5.如果发现服务生产者有多个时,需要挑选其中的一个服务器进行访问 该操作称之为负载均衡.
6.注册中心有心跳检测机制.如果连续3次访问生产者都没有响应则断定生产者宕机.
7.当发现生产者宕机之后,注册中心会更新服务列表数据,并且同步给所有的消费者.保证数据的一致性.
4.3 注册中心-zookeeper介绍
4.3.1 zookeeper介绍(zk)
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper包含一个简单的原语集,提供Java和C的接口。
ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在$zookeeper_home\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。(概述图片来源: [1] )
zk:服务调度器.
4.3.2 上传安装包
4.3.2 解压安装包
具体安装信息参见文档…
4.4 Dubbo框架介绍
Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
4.5 什么是RPC
RPC是远程过程调用(Remote Procedure Call)的缩写形式。
本地过程调用: 自己完成自己的任务.
远程过程调用: 通知第三方完成自己的任务.
不同的服务器之间的通信称之为rpc.
特点:
1).RPC调用的本质是代理对象的应用!!!
2).PRC调用就像调用本地服务一样,调用远程服务器!!!
5 Dubbo框架的入门案例
5.0 导入dubbo入门案例代码
1).入门案例位置
2).导入工作空间
3).修改POM.xml文件
3).STS导入项目
项目导入个数.
5.1定义中立的接口
说明: 接口是消费者与服务提供者之间数据通信的规范. 接口既不属于消费者,也不属于提供者.处于中立的方式. 减少代码的耦合性.
public interface UserService {
//查询全部的用户信息
List<User> findAll();
//新增用户入库操作.
@Transactional
void saveUser(User user);
}
引入jar包文件
在dubbo-jt中引入dubbo的jar包文件.
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
5.2定义服务提供者(生产者)
说明:服务器提供者主要负责业务的具体实现
5.2.1编辑接口的实现类
package com.jt.dubbo.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.dubbo.config.annotation.Service;
import com.jt.dubbo.mapper.UserMapper;
import com.jt.dubbo.pojo.User;
@Service(timeout=3000) //3秒超时 内部实现了rpc
//@org.springframework.stereotype.Service//将对象交给spring容器管理
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public List<User> findAll() {
System.out.println("我是第一个服务的提供者");
return userMapper.selectList(null);
}
@Override
public void saveUser(User user) {
userMapper.insert(user);
}
}
5.2.2编辑YML配置文件
server:
port: 9000 #定义端口
spring:
datasource:
#引入druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
#关于Dubbo配置
dubbo:
scan:
basePackages: com.jt #指定dubbo的包路径
application: #应用名称
name: provider-user #一个接口对应一个服务名称
registry:
address: zookeeper://192.168.126.129:2181 #?backup=192.168.126.129:2182,192.168.126.129:2183
protocol: #指定协议
name: dubbo #使用dubbo协议(tcp-ip) web-controller直接调用sso-Service
port: 20880 #每一个服务都有自己特定的端口 不能重复.
mybatis-plus:
type-aliases-package: com.jt.dubbo.pojo #配置别名包路径
mapper-locations: classpath:/mybatis/mappers/*.xml #添加mapper映射文件
configuration:
map-underscore-to-camel-case: true #开启驼峰映射规则
5.3定义服务消费者
说明:消费者主要负责业务的调用.
5.3.1编辑Controller
package com.jt.dubbo.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.dubbo.pojo.User;
import com.jt.dubbo.service.UserService;
@RestController
public class UserController {
////利用dubbo的方式为接口创建代理对象 利用rpc调用
@Reference //(loadbalance="leastactive")
private UserService userService; //代理对象
/**
* Dubbo框架调用特点:远程RPC调用就像调用自己本地服务一样简单
* @return
*/
@RequestMapping("/findAll")
public List<User> findAll(){
//远程调用时传递的对象数据必须序列化.
return userService.findAll();
}
@RequestMapping("/saveUser/{name}/{age}/{sex}")
public String saveUser(User user) {
userService.saveUser(user);
return "用户入库成功!!!";
}
}
5.3.2编辑YML配置文件
server:
port: 9001
dubbo:
scan:
basePackages: com.jt
application:
name: consumer-user #定义消费者名称
registry: #注册中心地址
address: zookeeper://192.168.126.129:2181 #?backup=192.168.126.129:2182,192.168.126.129:2183
5.3.3测试效果
6.Dubbo 高可用测试
6.1 测试Dubbo是否可以负载均衡
测试结果:dubbo默认采用是随机算法,实现了负载均衡
6.2 测试如果提供者宕机用户是否受到影响
测试结果: 服务宕机之后,由于有zk的支持,所有用户访问不受影响.
6.3 测试服务自动发现功能
说明:当服务器重启时,无需做任何的操作,程序就可以链接新的服务器.
6.4 如果zk宕机用户是否受到影响
说明:当zk服务器宕机,用户访问时短期内不会受到任何的影响.
问题1:如果这时提供者宕机, 问用户访问是否受到影响???
答: 用户访问不受影响, 因为消费者在访问提供者时,如果发现提供者宕机,则自己维护服务列表信息.
作业
1.完成阶段代码 用户数据校验 录视频 10分钟
2. 整理dubbo入门案例
简述dubbo调用过程
分成几部分3部分 每一部分的功能和作用 work文档. 20分钟
3. 在数据库中新增一张表 dog表 字段 id name age 准备5条测试数据.
以dubbo的方式展现dog表的记录.
接口 提供者 消费者 浏览器访问 代码完成. 20分钟
上一篇: 缓冲区溢出解密四