SpringBoot part4 day16

1 优化JSONP调用

修改页面JS校验:
SpringBoot part4 day16_第1张图片
SpringBoot part4 day16_第2张图片
SpringBoot part4 day16_第3张图片
后端异常后,前端没有报错信息,参数校验一直处于校验过程中,但是页面返回信息正常,因为jsonp返回的结果需要进行特殊的格式处理
需要对全局异常处理机制进行处理
SpringBoot part4 day16_第4张图片
全局异常处理机制的编写
利用参数callBack是否为jsonp跨域请求
SpringBoot part4 day16_第5张图片

@RestControllerAdvice   //aop+异常通知 是controller层的一个通知
@Slf4j
public class SystemException {

     /**
      * 确定该请求是一个跨域的JSONP请求时,才按照指定的格式返回!!!  callback(JSON)
      * 利用参数callback 判断是否为jsonp跨域, 如何获取???
      * */
    //当遇到某种类型的异常时才会执行
    @ExceptionHandler({RuntimeException.class})
    public Object exception(Exception e, HttpServletRequest request, HttpServletResponse response){
        log.error(e.getMessage(),e);
        e.printStackTrace();

        //1.获取callback请求参数
        String callback=request.getParameter("callback");
        //2.判断是否为jsonP的跨域请求
        if(StringUtils.hasLength(callback)){//如果有值则返回callback(JSON)
            JSONPObject jsonpObject=new JSONPObject(callback, SysResult.fail());
            return jsonpObject;

        }

        //如果出错,返回系统级别的报错数据即可
        return SysResult.fail();
    }


测试:

SpringBoot part4 day16_第6张图片
此时页面出现报错信息
SpringBoot part4 day16_第7张图片
跨域请求:浏览器发起的ajax请求违反了同源策略
实现方式: jsonp cors
数据通过F12可以查看,安全性差;而且不能对数据进行二次封装
jsonp 是利用script中的src属性发送请求获得数据,并将数据做特俗的格式封装后实现的调用
HttpClient 远程过程调用 服务A controller----service ------>服务B controller—service----mapper 业务结构繁琐
会被其他框架封装后使用,比如springCloud
直接由service层向后端服务器进行调用
SpringBoot part4 day16_第8张图片SOA思想 (面向服务的开发模型) 抛开http协议,以最简单的方式进行的关系调用
SpringBoot part4 day16_第9张图片
RPC JSONP,CORS也是一种RPC(但凡调用第三方都是RPC调用)
OSI模型的七层模型:
SpringBoot part4 day16_第10张图片
SpringBoot part4 day16_第11张图片
TCP安全,UDP不安全但是速度快

2 微服务调用思想

2.1传统方式调用的问题说明

SpringBoot part4 day16_第12张图片
SpringBoot part4 day16_第13张图片

2.2微服务思想-注册中心

前端服务器只负责页面的展现,真正耗费性能的是后端服务器
注册中心:1 服务的名称
2 HOST-PORT

1 首先是后端服务器启动,自动注册;
2 web服务器连接注册中心将注册信息同步(实时同步)到web服务器,并保存到本地;
3 web服务器检查信息后直接访问服务器,此时若有多台服务器要进行负载均衡(减轻了nginx的压力(以前是nginx实现负载均衡));
4 注册中心里面有心跳检测机制,将注册信息中相应服务器标识为down

SpringBoot part4 day16_第14张图片
微服务:架构设计采用分布式思想,当服务器发生故障时,可以实现自动化故障的迁移,无人为干预

2.3注册中心原理

微服务: 架构设计采用分布式思想,当服务器发生故障时,可以实现自动化的故障迁移.无需人为干预.
SpringBoot part4 day16_第15张图片
注册中心实现原理:
1.当服务器启动时,会将服务器的状态(服务名称/IP/端口) 一起写入注册中心
2.注册中心接收到服务器信息时,会动态的维护服务列表数据.
3/4.当客户端(消费者)启动时,首先会链接注册中心,获取所有的服务列表数据.并且将服务列表数据保存到本地.
5.当消费者执行业务调用时,如果有多个服务的生产者时,采用负载均衡的思想挑选其中的一个服务进行访问(RPC).
6.当服务器发生宕机时,由于注册中心有心跳检测机制,所有会动态的维护服务列表数据.会全网广播通知所有的客户端(消费者)更新服务列表数据. 在更新服务列表时,数据的同步会陷入阻塞的状态.

2.4 关于微服务思想-负载均衡说明

2.4.1集中式负载均衡
说明:所有的请求都必须由某个服务器进行统一管理
nginx是反向代理加上负载均衡 主要作用是反向代理
2.4.2客户端负载均衡
说明:请求发送之前,每个客户端都非常清除知道自己要访问的服务器

常见的注册中心: zookeeper(apache) eureka(springCloud)

1).什么是集中式的负载均衡 (nginx)
特点:
1).用户访问服务器时,自己不清楚访问的真实的服务器到底是谁,由nginx服务器动态的反向代理实现.
2).统一由负载均衡服务器进行负载. 问题 负载均衡服务器访问压力高.
客户端负载均衡
1).消费者在访问服务提供者时清楚的了解 到底应该访问哪台服务器.
2).由于每个客户端都进行负载均衡.相当于将压力均匀的分配给客户端.访问压力低.

核心: 1).nginx一般只负责反向代理
2).在微服务框架中 几乎都是客户端负载均衡服务器.

2.5注册中心zookeeper安装

SpringBoot part4 day16_第16张图片

3 Zookepper介绍

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper包含一个简单的原语集,提供Java和C的接口。
ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-3.4.3\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。
总结:Zookeeper负责服务的协调调度.当客户端发起请求时,返回正确的服务器地址.
1 下载
http://zookeeper.apache.org/releases.html.
SpringBoot part4 day16_第17张图片
下载路径,点击download
SpringBoot part4 day16_第18张图片
下载Zookeeper地址
http://mirrors.hust.edu.cn/apache/zookeeper/
SpringBoot part4 day16_第19张图片
2 zookeeper安装
上传或者下载安装包

SpringBoot part4 day16_第20张图片
解压并改名:
SpringBoot part4 day16_第21张图片
SpringBoot part4 day16_第22张图片
SpringBoot part4 day16_第23张图片
SpringBoot part4 day16_第24张图片
启动成功页面
SpringBoot part4 day16_第25张图片

zookeeper是java编写的程序,所以必须安装jdk

端口占用情况
80 nginx/oracal
8080 tomcat
3306 mysql
8066 mycat
6379 redis
26379 哨兵
2181 zookeeper

3.1Zookeeper集群的搭建

3.1.1关于集群相关思想
1 几台服务器可以搭建集群????
公式:存活节点>N/2(N宕机前节点数量)
算数计算:
1个节点能否搭建集群? 1-1 > 0.5 假 不能搭建集群
2个节点能否搭建集群? 2-1 > 1 假 不能搭建集群
3个节点能否搭建集群? 3-1 > 1.5 真 可以搭建集群
4个节点能否搭建集群> 4-1 > 2 真 可以搭建集群
结论:集群的最小单位是3台
2 集群为什么一般都是奇数台???
分析集群宕机的条件:
3个节点最多允许宕机1台. 奇数
4个节点最多允许宕机1台 偶数
说明: 由于搭建偶数台和搭建奇数台的容灾效果相同的,所以一般都是奇数个.
结论:集群搭建都是奇数台
3 什么是脑裂现象????
由于集群工作过程中,主机意外宕机,集群开始进行选举,如果出现多次连续平票的状态时,可能出现脑裂现象
SpringBoot part4 day16_第26张图片
两个人投票,脑裂现象的概率是 1/8
如何有效降低脑裂现象发生: 增加节点的数量
SpringBoot part4 day16_第27张图片
如何有效降低脑裂现象的发生 增加节点的数量

3.1.2搭建3 台zookeeper集群
关掉单台zookeeper
SpringBoot part4 day16_第28张图片
创建zkCluster文件
SpringBoot part4 day16_第29张图片
创建zk1 zk2 zk3
mkdir zk1 zk2 zk3
SpringBoot part4 day16_第30张图片
mkdir {zk1,zk2,zk3}/{data,log}
SpringBoot part4 day16_第31张图片
SpringBoot part4 day16_第32张图片
vim zk1/data/myid 依次添加为1,2,3
进入zookeeper的conf目录下复制文件
SpringBoot part4 day16_第33张图片
vim zoo1.cfg文件:
SpringBoot part4 day16_第34张图片

SpringBoot part4 day16_第35张图片
启动文件
SpringBoot part4 day16_第36张图片

3.2关于zk集群选举的规范

说明: zk集群选举规则是myid最大值优先的算法,如果选举结束,则剩余的节点当新主机的从机.
考题1: 如果依次启动1-7台zk节点
问1: 谁当主机? 4
问2: 谁永远不能当选主机? 1,2,3
SpringBoot part4 day16_第37张图片

3.3 ZK工作原理说明

Zookeeper集群中leader负责监控集群状态同步数据,follower主要负责客户端链接获取服务列表信息.同时参与投票.
SpringBoot part4 day16_第38张图片

4 Dubbo框架

4.1Dubbo框架介绍

Apache Dubbo |ˈdʌbəʊ| 提供了六大核心能力:面向接口代理的高性能RPC调用,智能容错和负载均衡,服务自动注册和发现,高度可扩展能力,运行期流量调度,可视化的服务治理与运维。

Doubble入门案例

4.2导入jar包

 <!--引入dubbo配置 -->
       <dependency>
            <groupId>com.alibaba.boot</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>0.2.0</version>
        </dependency>

4.3导入 入门案例

修改版本SpringBoot part4 day16_第39张图片
修改module中dubbo
SpringBoot part4 day16_第40张图片
在项目cgb2008_jt_1中右键粘贴
SpringBoot part4 day16_第41张图片
添加为pom项目 右键add as maven project
SpringBoot part4 day16_第42张图片

4.3.1项目的分析
1 先定义中立的接口 interface
接口中没有yml文件
SpringBoot part4 day16_第43张图片
interface接口项目接口:
SpringBoot part4 day16_第44张图片
UserService
SpringBoot part4 day16_第45张图片
2 定义服务的生产者
用TCP协议
SpringBoot part4 day16_第46张图片
接口的实现:

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);
	}
}

生产者和接口之间是依赖关系
说明:注意注解导入的是dubbo的注解
SpringBoot part4 day16_第47张图片
SpringBoot part4 day16_第48张图片
provider的application.yml
SpringBoot part4 day16_第49张图片

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                #开启驼峰映射规则

一般一个接口一个实现
在这里插入图片描述

SpringBoot part4 day16_第50张图片
tomcat端口9000运行,加载dubbo服务
SpringBoot part4 day16_第51张图片
一般修改两个地方:
SpringBoot part4 day16_第52张图片
3 生产者测试
启动生产者自动生成dubbo ip地址:
在这里插入图片描述
4 消费者
SpringBoot part4 day16_第53张图片

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 "用户入库成功!!!";
	}
}

为接口创建动态代理
SpringBoot part4 day16_第54张图片
编辑消费者的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

启动消费者(注意启动顺序,先有生产者再有消费者)
SpringBoot part4 day16_第55张图片
测试:
SpringBoot part4 day16_第56张图片

你可能感兴趣的:(springboot,分布式,zookeeper,java,spring)