2006-京淘Day18

it2023-02-05  46

1. Dubbo

1.1 Dubbo介绍

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

1.2 Dubbo特点

2 Dubbo入门案例

2.1 定义公共接口项目

说明:接口项目一般定义公共的部分,并且被第三方依赖.

2.2 服务提供者介绍

2.2.1 提供者代码结构

2.2.2 编辑实现类

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

2.2.3 编辑提供者配置文件

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的包路径 扫描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.3 服务消费者介绍

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

2.3.3 Dubbo入门案例测试

2.4 关于Dubbo框架知识点

2.4.1 问题1:如果其中一个服务器宕机 用户访问是否受限?

答:由于zk的帮助,使得程序永远可以访问正确的服务器.并且当服务重启时,duboo有服务的自动发现功能,消费者不需要重启即可以访问新的服务.

2.4.2 问题2:如果ZK集群短时间宕机,用户访问是否受限?

答: 用户的访问不受影响,由于消费者在本地存储服务列表信息,当访问故障机时,自动的将标识信息改为down属性.

2.5 Dubbo负载均衡策略

2.5.1 负载均衡种类

1.客户端负载均衡 Dubbo/SpringCloud等微服务框架 2.服务端负载均衡 说明:客户端发起请求之后,必须由统一的服务器进行负载均衡,所有的压力都在服务器中. NGINX

2.5.2 Dubbo负载均衡方式

@RestController public class UserController { //利用dubbo的方式为接口创建代理对象 利用rpc调用 //@Reference(loadbalance = "random") //默认策略 负载均衡随机策略 //@Reference(loadbalance = "roundrobin") //轮询方式 //@Reference(loadbalance = "consistenthash") //一致性hash 消费者绑定服务器提供者 @Reference(loadbalance = "leastactive") //挑选当前负载小的服务器进行访问 private UserService userService; }

3 京淘项目Dubbo改造

3.1 改造JT-SSO

3.1.1 添加jar包文件

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

3.1.2 创建DubboUserService接口

3.1.3 创建提供者实现类

3.1.4 编辑提供者YML配置文件

server: port: 8093 servlet: context-path: / spring: datasource: #引入druid数据源 #type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.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 mvc: view: prefix: /WEB-INF/views/ suffix: .jsp #mybatis-plush配置 mybatis-plus: type-aliases-package: com.jt.pojo mapper-locations: classpath:/mybatis/mappers/*.xml configuration: map-underscore-to-camel-case: true logging: level: com.jt.mapper: debug #关于Dubbo配置 dubbo: scan: basePackages: com.jt #指定dubbo的包路径 扫描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 #每一个服务都有自己特定的端口 不能重复.

3.1.5 启动服务提供者

测试Dubbo服务器启动是否正常.

3.2 改造服务消费者JT-WEB

3.2.1 注入Service接口

3.2.2 编辑消费者配置文件

server: port: 8092 spring: #定义springmvc视图解析器 mvc: view: prefix: /WEB-INF/views/ suffix: .jsp dubbo: scan: basePackages: com.jt application: name: consumer-web #定义消费者名称 registry: #注册中心地址 address: zookeeper://192.168.126.129:2181?backup=192.168.126.129:2182,192.168.126.129:2183

3.2.3 启动效果测试

4.用户模块实现

4.1 用戶注册

4.1.1 URL分析

根据url地址说明请求为同域请求. 参数信息:

4.1.2 页面JS分析

说明:根据分析获取返回值数据信息应该为SysResult对象

4.1.3 编辑UserController

/** * 需求: 实现用户信息注册 * 1.url请求地址: http://www.jt.com/user/doRegister * 2.请求参数: {password:_password,username:_username,phone:_phone}, * 3.返回值结果: SysResult对象 */ @RequestMapping("/doRegister") @ResponseBody //将数据转化为JSON public SysResult saveUser(User user){ //消费者给予dubbo协议将user对象进行远程网络数据传输. userService.saveUser(user); return SysResult.success(); }

4.1.4 编辑UserService

/** * 注意事项: * 1.暂时使用电话号码代替邮箱 * 2.密码进行md5加密. * 3.入库操作注意事务控制 * @param user */ @Override public void saveUser(User user) { String md5Pass = DigestUtils.md5DigestAsHex(user.getPassword().getBytes()); user.setEmail(user.getPhone()) .setPassword(md5Pass); userMapper.insert(user); }

4.1.5 页面效果展现

4.2 关于ZK数据存储结构

说明:在zk中数据的存储采用树形结构的方式保存 命令: [root@localhost bin]# sh zkCli.sh 查询命令: ls /…

4.3 用户单点登录原理介绍

4.3.1 传统方式登录存在的问题

说明: 如果采用SESSION的方式实现用户的登录操作,由于nginx负载均衡的策略,用户可以访问不同的服务器.但是Session不能共享,所以导致用户频繁的登录. 用户的体验不好.

4.3.2 SSO

单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联系统和应用软件的权限,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在多个应用系统中,**用户只需一次登录就可以访问所有相互信任的应用系统。**这种方式减少了由登录产生的时间消耗,辅助了用户管理,是目前比较流行的 [1]

4.3.3 京淘项目单点登录设计

实现步骤: 1.当用户输入用户名和密码点击登录时,将请求发送给JT-WEB消费者服务器. 2.JT-WEB服务器将用户信息传递给JT-SSO单点登录系统完成数据校验. 3.如果登录成功,则动态生成密钥信息,将user数据转化为json.保存到redis中. 注意超时时间的设定. 4.JT-SSO将登录的凭证 传给JT-WEB服务器. 5.JT-WEB服务器将用户密钥TICKET信息保存到用户的cookie中 注意超时时间设定. 6.如果登录不成功,则直接返回错误信息即可.

4.4 用户单点登录实现

4.4.1 页面url分析

4.4.2 页面参数分析

4.4.3 页面JS分析

4.4.4 编辑UserController

/** * 完成用户登录操作 * 1.url地址: http://www.jt.com/user/doLogin?r=0.9309436837648131 * 2.参数: {username:_username,password:_password}, * 3.返回值结果: SysResult对象 * * 4.Cookie: * 4.1 setPath("/") path表示如果需要获取cookie中的数据,则url地址所在路径设定. * url:http://www.jt.com/person/findAll * cookie.setPath("/"); 一般都是/ * cookie.setPath("/person"); * 4.2 setDomain("xxxxx") 设定cookie共享的域名地址. */ @RequestMapping("/doLogin") @ResponseBody public SysResult doLogin(User user, HttpServletResponse response){ String ticket = userService.doLogin(user); if(StringUtils.isEmpty(ticket)){ //说明用户名或者密码错误 return SysResult.fail(); }else{ //1.创建Cookie Cookie cookie = new Cookie("JT_TICKET",ticket); cookie.setMaxAge(7*24*60*60); //设定cookie存活有效期 cookie.setPath("/"); //设定cookie有效范围 cookie.setDomain("jt.com"); //设定cookie共享的域名 是实现单点登录必备要素 response.addCookie(cookie); return SysResult.success(); //表示用户登录成功!! } }

4.4.5 编辑UserService

/** * 1.获取用户信息校验数据库中是否有记录 * 2.有 开始执行单点登录流程 * 3.没有 直接返回null即可 * @param user * @return */ @Override public String doLogin(User user) { //username/password //1.将明文加密 String md5Pass = DigestUtils.md5DigestAsHex(user.getPassword().getBytes()); user.setPassword(md5Pass); QueryWrapper<User> queryWrapper = new QueryWrapper<>(user); //根据对象中不为null的属性当做where条件. User userDB = userMapper.selectOne(queryWrapper); if(userDB == null){ //用户名或密码错误 return null; }else{ //用户名和密码正确 实现单点登录操作 String ticket = UUID.randomUUID().toString(); //如果将数据保存到第三方 一般需要脱敏处理 userDB.setPassword("123456你信不??"); String userJSON = ObjectMapperUtil.toJSON(userDB); jedisCluster.setex(ticket, 7*24*60*60, userJSON); return ticket; } }

4.4.6 页面效果展现

最新回复(0)