cgb2010-京淘项目Day18
1.ZK集群搭建
说明:集体搭建内容,参见课前资料的文档.
1.1 搭建集群规则
规则: 剩余存活节点的数量 > N/2 N代表节点总数
计算:
1个节点 1-1 > 1/2 假的 一个节点不能搭建集群
2个节点 2-1 > 2/2 假的 二个节点不能搭建集群
3个节点 3-1 > 3/2 真的 集群的最小的单位3台.
4个节点 4-1 > 4/2 真的
1.2 为什么集群一般都是奇数台
从容灾性/经济性的角度考虑问题
奇数 3台 3-1 > 3/2 宕机1台可以正常工作
3-2 > 3/2 宕机2台集群崩溃
偶数 4台 4-1 > 2/4 宕机1台可以正常工作
4-2 > 4/2 宕机2台集群崩溃
答: 发现奇数台和偶数台的容灾性相同的,所以搭建奇数台更好.
1.3 zk集群选举规则
规则: myid最大值优先 只讨论1轮
考题:
编号 1,2,3,4,5,6,7 依次启动. 至少4台…
问题1: 谁当主机? 4当主…
问题2: 谁永远当不了主机? 1,2,3
2.Dubbo框架
2.1 Dubbo介绍
Dubbo(读音[ˈdʌbəʊ])是阿里巴巴公司开源的一个高性能优秀的服务框架(SOA),使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 [1] Spring框架无缝集成。
Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
2.2 Dubbo入门案例
2.2.1 修改配置文件
1).检查POM文件是否正确
2).修改SpringBoot版本
2.3 接口定义
说明: interface与被消费者/生产者(提供者)依赖.
2.4 编辑服务提供者
2.4.1 提供者代码结构
2.4.2 编辑Service实现类
`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.4.3 编辑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.5 编辑服务消费者
2.5.1 消费者代码结构
2.5.2 编辑Controller代码
2.5.3 编辑YML配置文件
2.5.4 页面效果测试
2.6 微服务框架测试
2.6.1 服务高可用测试
关闭一个服务提供者,检查用户的访问是否收到影响. 经过测试.用户访问不受影响.
2.6.2 zk高可用测试
将zk主机关闭,检查用户访问是否受限. 经过测试访问不受限制.
2.6.3 zk集群宕机测试
将zk集群全部关闭,检查用户访问是否受限?? 不受影响 因为消费者本地也有服务列表信息(之前缓存的)
2.7 关于负载均衡说明
2.7.1 集中式负载均衡
说明:统一由服务器进行负载均衡的调度. 反向代理机制.
2.7.2 客户端式负载均衡
2.7.3 Dubbo框架中负载均衡方式
1.ConsistentHashLoadBalance 一致性hash算法 消费者绑定唯一的服务提供者
2.LeastActiveLoadBalance 最小访问 挑选当前服务器压力最小的提供者进行访问.
3.RandomLoadBalance 随机算法 是默认的负载均衡机制
- RoundRobinLoadBalance 轮询机制
3.京淘项目Dubbo改造
3.1 导入jar包
`<!--引入dubbo配置 -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
3.2 定义中立接口
3.3 改造JT-MANAGE
3.3.1 定义实现类
3.3.2 编辑YML配置文件
`server:
port: 8091
servlet:
context-path: /
spring:
datasource:
#url: jdbc:mysql://192.168.126.129:8066/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
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的包路径
application: #应用名称
name: provider-item #一个接口对应一个服务名称
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.4 构建服务消费者-JT-WEB
3.4.1 编辑ItemController
3.4.2 编辑YML配置文件
`server:
port: 8092
spring: #定义springmvc视图解析器
mvc:
view:
prefix: /WEB-INF/views/
suffix: .jsp
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
4.商品前台展现
4.1 业务分析
说明:用户点击某个商品时,应该跳转到商品的展现页面item.jsp中.
数据获取规则:
需要查询后台服务器获取当前的商品信息,之后将数据保存到域对象中,通过el表达式动态获取${item.title }
数据1: Item对象信息
数据2: ItemDesc对象信息
4.2 编辑ItemController
`package com.jt.controller;
import com.alibaba.dubbo.config.annotation.Reference;
import com.jt.pojo.Item;
import com.jt.pojo.ItemDesc;
import com.jt.service.DubboItemService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Controller //页面跳转.......
public class ItemController {
//先启动服务消费者 暂时不校验是否有提供者
@Reference(check = false)
private DubboItemService itemService;
/**
*
* 业务需求: 根据商品id号查询商品/商品详情信息
* url地址: http://www.jt.com/items/562379.html
* 参数: restFul风格
* 返回值: 跳转页面item.jsp
* 页面取值: Item/ItemDesc对象
*/
@RequestMapping("/items/{itemId}")
public String findItemById(@PathVariable Long itemId, Model model){
Item item = itemService.findItemById(itemId);
ItemDesc itemDesc = itemService.findItemDescById(itemId);
//需要将数据保存到域对象中
model.addAttribute("item", item);
model.addAttribute("itemDesc", itemDesc);
return "item";
}
}
4.3 编辑ItemService
`package com.jt.web.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.jt.mapper.ItemDescMapper;
import com.jt.mapper.ItemMapper;
import com.jt.pojo.Item;
import com.jt.pojo.ItemDesc;
import com.jt.service.DubboItemService;
import org.springframework.beans.factory.annotation.Autowired;
@Service(timeout = 3000)
public class DubboItemServiceImpl implements DubboItemService {
@Autowired
private ItemMapper itemMapper;
@Autowired
private ItemDescMapper itemDescMapper;
//查询商品信息
@Override
public Item findItemById(Long itemId) {
return itemMapper.selectById(itemId);
}
//查询商品详情信息
@Override
public ItemDesc findItemDescById(Long itemId) {
return itemDescMapper.selectById(itemId);
}
}
4.4 效果展现
4.5 关于POJO报错说明
说明:如果遇到这样的报错信息,则需要重启服务器即可.
原因: 由于热部署速度很快 导致zk服务器内部出现了2条一模一样的服务信息.不知道应该访问哪个报错.
- 用户模块改造
==========
5.1 编辑DubboUserService
5.2 编辑YML配置文件
`server:
port: 8093
servlet:
context-path: /
spring:
datasource:
#url: jdbc:mysql://192.168.126.129:8066/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
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的包路径
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: 20881 #每一个服务都有自己特定的端口 不能重复.
- 用户注册实现
==========
6.1 业务分析
6.1.1 页面URL分析
6.1.2 参数分析
6.1.3 检查页面JS
6.2 编辑JT-WEB UserController
6.3 编辑JT-SSO UserService
package com.jt.service;
import com.alibaba.dubbo.config.annotation.Service;
import com.jt.mapper.UserMapper;
import com.jt.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
@Service(timeout = 3000)
public class DubboUserServiceImpl implements DubboUserService{
@Autowired
private UserMapper userMapper;
@Override
public void saveUser(User user) {
//将密码md5加密
byte[] bytes = user.getPassword().getBytes();
String md5Pass = DigestUtils.md5DigestAsHex(bytes);
user.setPassword(md5Pass);
//要求email不为null 暂时使用电话代替
user.setEmail(user.getPhone());
userMapper.insert(user);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。