1).定義接口html
2).定義接口代碼java
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的包路徑 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
1).測試當服務器宕機,用戶訪問是否受影響. 用戶訪問不受影響. zk心跳檢測機制
2).測試當zk集羣宕機,用戶訪問是否受影響. 消費者在本地有服務列表數據,本身維護.
3).測試是否由負載均衡的效果 用戶訪問有負載均衡的效果mysql
1.服務端負載均衡(集中式負載均衡)
說明:用戶訪問服務器時不清楚真實的服務器究竟是誰,由負載均衡服務器動態管理
典型表明:NGINX
通常nginx服務器作反向代理使用,負載均衡只是提供服務
2.客戶端負載均衡
說明:採用微服務架構時,當消費者訪問服務提供者時,因爲框架內部已經實現了負載均衡的策略,因此消費者訪問提供者時已經完成了負載均衡的機制.因此將全部的壓力平衡到了各個消費者中.nginx
默認條件下就是隨機算法web
<!--引入dubbo配置 --> <dependency> <groupId>com.alibaba.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>0.2.0</version> </dependency>
說明:在jt-common中添加接口文件redis
server: port: 8093 servlet: context-path: / #在根目錄中發佈 缺省值. 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 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: 20880 #每個服務都有本身特定的端口 不能重複.
server: port: 8092 spring: #定義springmvc視圖解析器 mvc: view: prefix: /WEB-INF/views/ suffix: .jsp #配置dubbo消費者 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
1).頁面url地址算法
2.頁面提交參數spring
3.頁面JS分析sql
/** * 完成用戶的註冊操做 * url地址: http://www.jt.com/user/doRegister * Request Method: POST * 請求參數: * password: admin123 * username: admin123123123 * phone: 13111112225 * 返回值類型: * SysResult對象 */ @RequestMapping("/doRegister") @ResponseBody public SysResult saveUser(User user){ //利用dubbo進行RPC調用 dubboUserService.saveUser(user); return SysResult.success(); }
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方式進行加密處理 String password = user.getPassword(); String md5Pass = DigestUtils.md5DigestAsHex(password.getBytes()); user.setEmail(user.getPhone()).setPassword(md5Pass); userMapper.insert(user); } }
單點登陸(SingleSignOn,SSO),就是經過用戶的一次性鑑別登陸。當用戶在身份認證服務器上登陸一次之後,便可得到訪問單點登陸系統中其餘關聯繫統和應用軟件的權限,同時這種實現是不須要管理員對用戶的登陸狀態或其餘信息進行修改的,這意味着在多個應用系統中,用戶只需一次登陸就能夠訪問全部相互信任的應用系統。這種方式減小了由登陸產生的時間消耗,輔助了用戶管理,是目前比較流行的apache
實現步驟:
1.用戶輸入用戶名和密碼以後點擊登陸按鈕進行登陸操做.
2.JT-WEB向JT-SSO發送請求,完成數據校驗
3.當JT-SSO獲取數據信息以後,完成用戶的校驗.若是校驗經過則將用戶信息轉化爲json.而且動態生成UUID.將數據保存到redis中,而且返回值uuid.
若是校驗不存在時,直接返回"不存在"便可
4.JT-SSO將數據返回給JT-WEB服務器.
5.若是登陸成功,則將用戶UUID保存到客戶端的cookie中.
1).url請求
2).url參數
3).頁面JS分析
/** * 業務:完成用戶登陸操做 * url地址: http://www.jt.com/user/doLogin?r=0.35842191622936337 * 參數: * username: admin123 * password: admin123456 * 返回值: SysResult對象 * * 業務具體實現: * 1.校驗用戶名和密碼是否正確 * 2.判斷返回值結果是否爲null 用戶名和密碼有誤 返回201狀態碼 * 3.若是返回值結果不爲null uuid保存到cookie中便可. * * Cookie知識介紹: * 1.cookie.setPath("/") 根目錄有效 * url1: www.jt.com/addUser * url2: www.jt.com/user/addUser * * 2. cookie.setDomain("域名地址"); cookie在哪一個域名中共享 * 例子1: cookie.setDomain("www.jt.com"); * 只有在www.jt.com的域名中有效 * * cookie.setDomain("jt.com"); * 只有在jt.com結尾的域名中有效 * */ @RequestMapping("/doLogin") @ResponseBody public SysResult doLogin(User user, HttpServletResponse response){ String uuid = dubboUserService.doLogin(user); if(StringUtils.isEmpty(uuid)){ return SysResult.fail(); } //將uuid保存到Cookie中 Cookie cookie = new Cookie("JT_TICKET",uuid); cookie.setMaxAge(30*24*60*60); //讓cookie 30天有效 cookie.setPath("/"); //cookie在哪一個url路徑生效 cookie.setDomain("jt.com"); //設定cookie共享 response.addCookie(cookie); return SysResult.success(); }
/** * 1.根據用戶名和密碼查詢後端服務器數據 * 將密碼加密處理 * @param user * @return */ @Override public String doLogin(User user) { String md5Pass = DigestUtils.md5DigestAsHex(user.getPassword().getBytes()); user.setPassword(md5Pass); QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);//u/p不能 //根據對象中不爲空的屬性,充當where條件. User userDB = userMapper.selectOne(queryWrapper); if(userDB == null){ //根據用戶名和密碼錯誤 return null; } //開始進行單點登陸業務操做 String uuid = UUID.randomUUID() .toString() .replace("-", ""); userDB.setPassword("123456你信不?"); //去除有效信息. String userJSON = ObjectMapperUtil.toJSON(userDB); jedisCluster.setex(uuid, 30*24*60*60, userJSON); return uuid; }
思路: 用戶經過TICKET信息,利用JSONP的方式動態獲取遠程的服務器數據信息.以後將數據返回以後 回顯數據.
/** * 業務說明: * 經過跨域請求方式,獲取用戶的JSON數據. * 1.url地址: http://sso.jt.com/user/query/efd321aec0ca4cd6a319b49bd0bed2db?callback=jsonp1605775149414&_=1605775149460 * 2.請求參數: ticket信息 * 3.返回值: SysResult對象 (userJSON) * 需求: 經過ticket信息獲取user JSON串 */ @RequestMapping("/query/{ticket}") public JSONPObject findUserByTicket(@PathVariable String ticket,String callback){ String userJSON = jedisCluster.get(ticket); if(StringUtils.isEmpty(userJSON)){ return new JSONPObject(callback, SysResult.fail()); }else{ return new JSONPObject(callback, SysResult.success(userJSON)); } }
當用戶點擊退出操做時,應該重定向到系統首頁.同時刪除redis信息/Cookie信息.
/** * 完成用戶退出操做 * url地址:http://www.jt.com/user/logout.html * 參數: 沒有參數 * 返回值: String 重定向到系統首頁 * 業務: * 1.刪除redis K-V 獲取ticket信息 * 2.刪除cookie */ @RequestMapping("/logout") public String logout(HttpServletRequest request,HttpServletResponse response){ //1.獲取Cookie中的JT_TICKET值 Cookie[] cookies = request.getCookies(); if(cookies != null && cookies.length>0){ for (Cookie cookie : cookies){ if(cookie.getName().equals("JT_TICKET")){ String ticket = cookie.getValue(); //redis刪除ticket信息 jedisCluster.del(ticket); cookie.setMaxAge(0); //0表示當即刪除 //規則cookie若是須要操做,必須嚴格定義 cookie.setPath("/"); cookie.setDomain("jt.com"); response.addCookie(cookie); } } } return "redirect:/"; }
當用戶點擊商品時應該跳轉到商品的展示頁面,在頁面中應該展示2部分數據.item數據/itemDesc數據. item.jsp頁面
數據取值方式:
1.獲取item信息 ${item.title }
2.獲取ItemDesc數據 ${itemDesc.itemDesc}
server: port: 8091 servlet: context-path: / #在根目錄中發佈 缺省值. 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 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 #配置manage 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: 20881 #每個服務都有本身特定的端口 不能重複.
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 javax.xml.ws.RequestWrapper; @Controller public class ItemController { @Reference(check = false) private DubboItemService itemService; /** * 實現商品的展示 * url: http://www.jt.com/items/562379.html * 參數: 562379商品ID號 * 返回值: item.jsp * 頁面取值: item對象/itemDesc對象 * {item.id/title} */ @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"; } }
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); } }
說明:當影虎點擊購物車按鈕時,應該跳轉到購物車頁面
頁面名稱: cart.jsp
頁面數據: ${cartList}
package com.jt.pojo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.experimental.Accessors; @TableName("tb_cart") @Data @Accessors(chain = true) public class Cart extends BasePojo{ @TableId(type = IdType.AUTO) //主鍵自增 private Long id; //購物車Id號 private Long userId; //用戶Id號 private Long itemId; //商品id號 private String itemTitle; //商品標題 private String itemImage; //商品圖片信息 private Long itemPrice; private Integer num; }
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <artifactId>jt-cart</artifactId> <parent> <artifactId>jt2007</artifactId> <groupId>com.jt</groupId> <version>1.0-SNAPSHOT</version> </parent> <!--3.依賴工具API--> <dependencies> <dependency> <groupId>com.jt</groupId> <artifactId>jt-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <!--4.添加maven插件--> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>