欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

京淘实训Day16-跨域-dubbo

程序员文章站 2022-03-29 14:49:09
...

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 简述搜索引擎的工作原理

倒排索引: 根据关键字,检索文章的位置
京淘实训Day16-跨域-dubbo

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是当下主流的一种跨域的访问形式,当下几乎所有的主流的浏览器其实都可以进行跨域的访问.浏览器在发起跨域的访问时新增一个请求头信息,来标识跨域访问.

浏览器自动拼接请求头,之后实现了跨域的访问.
京淘实训Day16-跨域-dubbo

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业务说明

当用户添加用户名时,需要与后端服务器进行数据的校验.如果后端数据库中已经存在该用户信息.则提示该用户已存在. 如果数据库没有该数据,则提示用户名可以使用.

京淘实训Day16-跨域-dubbo

3.1如何实现

关键问题: 客户端服务器: www.jt.com
后端服务器: sso.jt.com
2台服务器之间应该如何通信???

远程服务器通信方式:
1. httpClient 步骤繁琐.
2. cors 跨域访问
3. jsonp跨域访问

3.2 用户注册页面分析

1).说明:通过F12开发者工具进行监控,发现该请求采用jsonp的形式进行跨域.
京淘实训Day16-跨域-dubbo

2.查询页面JS的位置
京淘实训Day16-跨域-dubbo

3).ajax js写法
京淘实训Day16-跨域-dubbo

3.3 用户数据校验的业务接口

京淘实训Day16-跨域-dubbo

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 页面效果展现

京淘实训Day16-跨域-dubbo

4. Dubbo框架

4.1 使用框架的目的

1.以一种统一的方式实现前后端的调用.
2.要求业务调用实现高可用机制.
3.实现服务的自动的发现功能.

京淘实训Day16-跨域-dubbo
上述业务系统的弊端
1). 业务服务之间进行访问时,都会经过nginx服务器.造成nignx服务器负载压力高.
2).nginx服务器没办法实现服务器的高可用.只能做到当访问的服务器宕机时,nginx会访问下一台服务器.保证服务的正常的运行.(没有高可用)
3).如果服务器数量发生了变化.则需要手动的修改nginx的配置文件 这样的方式不够便捷.

4.2 服务器端服务的自动功能的实现----注册中心(微服务)

目的: 能否自动的实现服务的注册和发现.当服务开启之后无需编辑任何的配置文件.程序就可以正常的调用.如果后端的服务器发生了宕机的现象.用户也无需干预.可以自动的实现服务的剔除.
京淘实训Day16-跨域-dubbo
步骤:
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 上传安装包

京淘实训Day16-跨域-dubbo

4.3.2 解压安装包

京淘实训Day16-跨域-dubbo
具体安装信息参见文档…

4.4 Dubbo框架介绍

Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
京淘实训Day16-跨域-dubbo

4.5 什么是RPC

RPC是远程过程调用(Remote Procedure Call)的缩写形式。
本地过程调用: 自己完成自己的任务.
远程过程调用: 通知第三方完成自己的任务.
不同的服务器之间的通信称之为rpc.

特点:
1).RPC调用的本质是代理对象的应用!!!
2).PRC调用就像调用本地服务一样,调用远程服务器!!!

京淘实训Day16-跨域-dubbo

5 Dubbo框架的入门案例

5.0 导入dubbo入门案例代码

1).入门案例位置
京淘实训Day16-跨域-dubbo
2).导入工作空间
京淘实训Day16-跨域-dubbo
3).修改POM.xml文件
京淘实训Day16-跨域-dubbo
京淘实训Day16-跨域-dubbo
3).STS导入项目
京淘实训Day16-跨域-dubbo
项目导入个数.
京淘实训Day16-跨域-dubbo

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测试效果

京淘实训Day16-跨域-dubbo

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分钟

相关标签: 实训