CGB2005-京淘17

1.HttpClient远程调用说明

1.1 需求说明:

需求:根据userId查询用户的信息.
1.用户的url地址: http://www.jt.com/findUserById/7;
2.需要在jt-web的Controller中动态的接收数据.将请求转给sso单点登录系统
url:http://sso.jt.com/findUserById/7
3.在jt-sso中的Controller根据userId查询用户信息.

1.2 编辑jt-web Controller

/**
     * 为了测试httpClient 实现业务功能查询用户信息
     * url地址:http://www.jt.com/user/findUserById/7
     * 参数:  7用户ID
     * 返回值: user对象
     */
    @RequestMapping("/findUserById/{userId}")
    @ResponseBody
    public User findUserById(@PathVariable Long userId){
    
    

        return userService.findUserById(userId);
    }

1.3 编辑前端 Service

@Service
public class UserServiceImpl implements UserService{
    
    


    /**
     * 由jt-web向jt-sso进行数据的请求.之后获取数据.
     * @param userId
     * @return
     */
    @Override
    public User findUserById(Long userId) {
    
    
        //1.定义url地址
        String url = "http://sso.jt.com/user/findUserById/"+userId;
        HttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
    
    
            HttpResponse httpResponse = httpClient.execute(httpGet);
            if(httpResponse.getStatusLine().getStatusCode() == 200){
    
    
                HttpEntity httpEntity = httpResponse.getEntity();
                //json格式
                String result = EntityUtils.toString(httpEntity, "UTF-8");
                return ObjectMapperUtil.toObject(result, User.class);
            }else{
    
    
                throw new RuntimeException("请求失败,请校验地址信息");
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}

1.4 编辑后端 Controller

 /**
     * 测试httpClient调用方式
     * url地址: http://sso.jt.com/user/findUserById/"+userId
     * 返回:  user对象的JSON数据
     */
    @RequestMapping("/findUserById/{userId}")
    public User findUserById(@PathVariable Long userId){
    
    

        return userService.findUserById(userId);
    }

1.5 编辑后端 Service

	@Override
    public User findUserById(Long userId) {
    
    

        return userMapper.selectById(userId);
    }

1.6 HttpClient调用流程图

在这里插入图片描述

2.Dubbo

2.1SOA思想

知识回顾: 面向对象的思想/ 面向接口开发 /面向切面开发 /面向服务开发

面向服务的架构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)进行拆分,并通过这些服务之间定义良好的接口和协议联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构件在各种各样的系统中的服务可以以一种统一和通用的方式进行交互。
概括:SOA思想要求按照业务将服务进行拆分,之后按照同一的中立的接口进行交互.
在这里插入图片描述

2.2 RPC(概念)

在这里插入图片描述
远程过程调用:
在服务之间,由第三方完成自己的任务的过程称之为远程过程调用.

2.3 微服务调用原理说明

标准:
1.根据业务拆分的思想 进行了分布式的设计
2.当服务发生异常时可以自动的实现故障的迁移 无需人为的干预.

2.3.1 传统服务调用方式

说明: 由于nginx做负载均衡时需要依赖配置文件.但是当服务器新增/减少时.都需要手动的修改.不能自动化的实现.所以暂时达不到微服务的标准.
在这里插入图片描述

2.3.2 微服务的调用原理介绍

在这里插入图片描述
步骤:
1.当服务的提供者启动时,会将自己的服务信息(服务名称/IP/端口号)进行记录
2.服务注册中心需要记录提供者的信息 维护服务列表
3.当服务消费者启动时会链接注册中心.
4.从注册中心中获取服务列表信息,方便下次调用
5.当消费者调用服务时,会根据负载均衡的机制挑选其中的一个服务提供者进行访问.
6.当服务提供者宕机时,由于注册中心有心跳检测机制,会维护服务列表.当宕机的提供者标识为down
7.当服务列表维护之后,会全网广播通知所有服务器的消费者更新服务列表信息.

2.4 关于集群说明

2.4.1 为什么集群是奇数台

原则: 搭建集群必须满足公式 现有的节点数量 > N/2
为什么集群的最小单位是3台:
假设: 1台 1-1=0 > 1/2 假的
2台 2-1=1 > 2/2 假的
3台 3-1=2 > 3/2 真的 3台是搭建集群的最小单位.
4台 4-1=3 > 4/2 真的 只要大约3台都可以搭建集群.

	集群中最多允许宕机的台数为多少???
					  3台最多允许宕机几台?    最多宕机1台
					  4台最多允许宕机几台?    最多宕机1台 

从实用性的角度考虑问题 发现搭建奇数台和偶数台的容灾能力相同.所以选用奇数台.

2.4.2 zk集群选举的原理

原理说明: zk集群的选举根据最大值优先的规则,进行选举. 如果集群一旦超过半数以上的票数同意,则当选主机,同时选举结束.

问题: 有1,2,3,4,5,6,7节点依次启动.
问题1: 谁当主机? 4当主机
问题2: 哪几台永远不能当选主机? 1 2 3

2.5 Dubbo框架介绍

2.5.1 官网介绍

Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
在这里插入图片描述

2.5.2 Dubbo特性

在这里插入图片描述

2.5.3 Dubbo工作原理

在这里插入图片描述

2.6 Dubbo入门案例

2.6.1 导入项目方式

在这里插入图片描述

2.6.2 导入项目

在这里插入图片描述
在这里插入图片描述

2.6.3 定义公共的第三方接口项目

在这里插入图片描述

2.6.3 提供者的说明

2.6.3.1 编辑Dubbo实现类

package com.jt.dubbo.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.jt.dubbo.mapper.UserMapper;
import com.jt.dubbo.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;
@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);
	}
}

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

2.6.4 服务消费者说明

2.6.4.1 编辑Controller层

package com.jt.dubbo.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.dubbo.pojo.User;
import com.jt.dubbo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {
    
    
	
	利用dubbo的方式为接口创建代理对象 利用rpc调用
	//check=false 先启动提供者/消费者没有关系
	@Reference(check = false,timeout = 3000) //(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 "用户入库成功!!!";
	}
}

2.6.4.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

2.6.4.3 消费者启动测试

在这里插入图片描述

2.6.5 关闭Dubbo面试题

问题1: 如果将其中的一个服务的提供者关闭,问 用户访问是否受影响?? 不受任何影响
问题2: 如果将dubbo中的注册中心全部关闭,问用户访问是否受到影响??? 不受影响,因为消费者将服务列表数据保存到本地.

作业

  1. 熟悉Dubbo框架的调用原理.

  2. 自己新创建一个项目要求实现Dubbo的结构.并且实现user的CURD相关操作.

    http://xxxxxxxxx:xxx/findUserById

猜你喜欢

转载自blog.csdn.net/qq_16804847/article/details/108614896