=========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.服務端負載均衡
說明:客戶端發起請求以後,必須由統一的服務器進行負載均衡,全部的壓力都在服務器中.
NGINX
sql
`@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; } }`