京淘实训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分钟

猜你喜欢

转载自blog.csdn.net/qq_16804847/article/details/107013193
今日推荐