=========java
Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。mysql
说明:接口项目通常定义公共的部分,而且被第三方依赖.nginx
`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); } }`
`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 #开启驼峰映射规则`
`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 "用户入库成功!!!"; } }`
`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`
答:因为zk的帮助,使得程序永远能够访问正确的服务器.而且当服务重启时,duboo有服务的自动发现功能,消费者不须要重启便可以访问新的服务.web
答: 用户的访问不受影响,因为消费者在本地存储服务列表信息,当访问故障机时,自动的将标识信息改成down属性.redis
1.客户端负载均衡
Dubbo/SpringCloud等微服务框架spring
2.服务端负载均衡
说明:客户端发起请求以后,必须由统一的服务器进行负载均衡,全部的压力都在服务器中.
NGINXsql
`@RestController public class UserController { //利用dubbo的方式为接口建立代理对象 利用rpc调用 //@Reference(loadbalance = "random") //默认策略 负载均衡随机策略 //@Reference(loadbalance = "roundrobin") //轮询方式 //@Reference(loadbalance = "consistenthash") //一致性hash 消费者绑定服务器提供者 @Reference(loadbalance = "leastactive") //挑选当前负载小的服务器进行访问 private UserService userService; }`
`<!--引入dubbo配置 --> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.2.0</version> </dependency>`
`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 #每个服务都有本身特定的端口 不能重复.`
测试Dubbo服务器启动是否正常.数据库
`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`
根据url地址说明请求为同域请求.
参数信息:json
说明:根据分析获取返回值数据信息应该为SysResult对象服务器
`/** * 需求: 实现用户信息注册 * 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(); }`
`/** * 注意事项: * 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); }`
说明:在zk中数据的存储采用树形结构的方式保存
命令: [root@localhost bin]# sh zkCli.sh
查询命令: ls /…
说明: 若是采用SESSION的方式实现用户的登陆操做,因为nginx负载均衡的策略,用户能够访问不一样的服务器.可是Session不能共享,因此致使用户频繁的登陆. 用户的体验很差.
单点登陆(SingleSignOn,SSO),就是经过用户的一次性鉴别登陆。当用户在身份认证服务器上登陆一次之后,便可得到访问单点登陆系统中其余关联系统和应用软件的权限,同时这种实现是不须要管理员对用户的登陆状态或其余信息进行修改的,这意味着在多个应用系统中,用户只需一次登陆就能够访问全部相互信任的应用系统。这种方式减小了由登陆产生的时间消耗,辅助了用户管理,是目前比较流行的 [1]
实现步骤:
1.当用户输入用户名和密码点击登陆时,将请求发送给JT-WEB消费者服务器.
2.JT-WEB服务器将用户信息传递给JT-SSO单点登陆系统完成数据校验.
3.若是登陆成功,则动态生成密钥信息,将user数据转化为json.保存到redis中. 注意超时时间的设定.
4.JT-SSO将登陆的凭证 传给JT-WEB服务器.
5.JT-WEB服务器将用户密钥TICKET信息保存到用户的cookie中 注意超时时间设定.
6.若是登陆不成功,则直接返回错误信息便可.
`/** * 完成用户登陆操做 * 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(); //表示用户登陆成功!! } }`
`/** * 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; } }`