springboot实现用户统一认证、管理(单点登录)

大家好,我是雄雄,欢迎关注微信公众号:雄雄的小课堂

前言

现在是:2022年5月25日13:44:16

最近和模拟登录杠上了,这不,又来了个需求,还是以这个技术点入手的。
需求大概是这样的:为了统一管理系统的用户,上游平台做了个统一认证平台,所有用户进入子系统只有一个入口,即:上游平台登录入口,新用户也是上游平台进行添加;子系统的用户登录和注册模块都屏蔽掉。

设计技能点

  1. 前端:Vue
  2. 后端:springboot (bladex框架)
  3. 数据库:mysql 5.7及以上

实现思路

  1. 上游平台通过回调接口,将用户和组织机构同步至子系统
  2. 上游平台通过url在地址栏中挂sessionid的方式访问子系统的登录页面
  3. 子系统检地址栏中是否有sessionid,如果有,则拿着sessionid去上游系统获取用户信息,然后在子系统中拿着用户信息自动登录
  4. 如果地址栏中没有sessionid,则需要带着子系统的登录地址,重定向至上游平台(上游平台怎么处理的,我就不知道了,我猜测,如果用户未在上游平台登录,则不带sessionid来的子系统,如果登录了则会带着过来。所以重定向到上游平台时,应该是让用户重新进行登录的)
  5. 当用户点击退出时,清除子系统的用户登录状态的同时还需要清除上游系统,且重定向至上游平台的登录页面

代码实现

回调接口实现了两个功能:

  • 同步组织机构
  • 同步用户信息

为了后期维护方便,前后端所有调用外部的地址,从接口中获取数据等均单独提取出来了,这样也能更好的实现复用。

  1. 统一接口管理SsoLoginConstant
	package org.springblade.modules.system.util;/*** @Description: TODO* @author: 穆雄雄* @date: 2022/5/17 下午 2:40* 放一些公共的常量* @Return:*/public interface SsoLoginConstant {/*** 统一认证平台的地址*/public final static String SSO_URL = "http://************";/*** 登录鉴权*/public final static  String CHECKLOGIN_URL =SSO_URL+ "/check_login";/*** 查询平台用户信息*/public final static  String QUERYUSER_URL =SSO_URL+ "/get_user";/*** 查询平台组织机构信息*/public final static String QUERYDEPARTMENT_URL =SSO_URL+ "/get_department";/*** 退出系统*/public final static String APILOGOUT_URL =SSO_URL+ "/api_logout";}
  1. 公用Service层接口:
package org.springblade.modules.system.service;import org.springblade.core.tool.api.R;import org.springframework.web.bind.annotation.RequestBody;/*** @author: muxiongxiong* @date: 2022年05月21日 上午 8:41* 公众号:雄雄的小课堂* 博客:https://blog.csdn.net/qq_34137397* 个人站:http://www.穆雄雄.com* 个人站:http://www.muxiongxiong.cn* @Description: 类的描述:单点登录业务层接口*/public interface ISsoLoginService {/*** @Description: 登录鉴权* @author: 穆雄雄* @date: 2022/5/21 上午 8:54No such property: code for class: Script1* @Return:*/String checkLogin(String ssoSessionKey);/*** @Description: 查询平台用户信息* @author: 穆雄雄* @date: 2022/5/21 上午 8:42* 查询平台用户信息* @Return:*/String getUser(String projectKey);/*** @Description: 查询平台组织机构信息* @author: 穆雄雄* @date: 2022/5/21 上午 8:50* 查询平台用户信息* @Return: java.lang.String*/String getDepartment(String projectKey);/*** @Description: 上传平台用户信息* @author: 穆雄雄* @date: 2022/5/21 上午 9:24* @Return: java.lang.String*/R pullUserInfo(@RequestBody String val);/*** @Description: 退出* @author: 穆雄雄* @date: 2022年5月25日15:34:58No such property: code for class: Script1* @Return:*/String apiLogout(String ssoSessionKey);}
  1. Service层实现类:
	package org.springblade.modules.system.service.impl;import cn.hutool.http.HttpUtil;import com.alibaba.fastjson.JSONArray;import com.alibaba.fastjson.JSONObject;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;import org.apache.commons.lang.StringUtils;import org.springblade.core.tool.api.R;import org.springblade.modules.system.entity.Dept;import org.springblade.modules.system.entity.User;import org.springblade.modules.system.entity.UserService;import org.springblade.modules.system.service.IDeptService;import org.springblade.modules.system.service.ISsoLoginService;import org.springblade.modules.system.service.IUserService;import org.springblade.modules.system.util.SsoLoginConstant;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.HashMap;import java.util.Map;/*** @author: muxiongxiong* @date: 2022年05月21日 上午 8:51* 公众号:雄雄的小课堂* 博客:https://blog.csdn.net/qq_34137397* 个人站:http://www.穆雄雄.com* 个人站:http://www.muxiongxiong.cn* @Description: 类的描述*/@Servicepublic class SsoLoginServiceImpl implements ISsoLoginService {@Autowiredprivate IUserService userService;@Autowiredprivate IDeptService deptService;/*** 登录鉴权*/@Overridepublic String checkLogin(String ssoSessionKey) {JSONObject jsonObjectResult = new JSONObject();//请求接口地址String url = SsoLoginConstant.CHECKLOGIN_URL;Map<String, Object> paramMap = new HashMap<String, Object>();paramMap.put("ssoSessionKey", ssoSessionKey);try {String body = HttpUtil.createPost(url).form(paramMap).execute().body();if (StringUtils.isBlank(body)) {jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}JSONObject obj = JSONObject.parseObject(body);if (obj == null) {jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}String code = obj.get("code").toString();if ("200".equals(code)) {jsonObjectResult.put("code", 200);jsonObjectResult.put("msg", "请求成功");jsonObjectResult.put("data", obj.get("data"));jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}else{jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}} catch (Exception e) {e.printStackTrace();}return jsonObjectResult.toJSONString();}/*** 获取平台用户*/@Overridepublic String getUser(String projectKey) {JSONObject jsonObjectResult = new JSONObject();//请求接口地址String url = SsoLoginConstant.QUERYUSER_URL;Map<String, Object> paramMap = new HashMap<String, Object>();paramMap.put("projectKey", projectKey);try {String body = HttpUtil.createGet(url).form(paramMap).execute().body();if (StringUtils.isBlank(body)) {jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}JSONObject obj = JSONObject.parseObject(body);if (obj == null) {jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}String code = obj.get("code").toString();if ("200".equals(code)) {jsonObjectResult.put("code", 200);jsonObjectResult.put("msg", "请求成功");jsonObjectResult.put("data", obj.get("data"));jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}} catch (Exception e) {e.printStackTrace();}return jsonObjectResult.toJSONString();}/*** 获取组织机构*/@Overridepublic String getDepartment(String projectKey) {JSONObject jsonObjectResult = new JSONObject();//请求接口地址String url = SsoLoginConstant.QUERYDEPARTMENT_URL;Map<String, Object> paramMap = new HashMap<String, Object>();paramMap.put("projectKey", projectKey);try {String body = HttpUtil.createGet(url).form(paramMap).execute().body();if (StringUtils.isBlank(body)) {jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}JSONObject obj = JSONObject.parseObject(body);if (obj == null) {jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}String code = obj.get("code").toString();if ("200".equals(code)) {jsonObjectResult.put("code", 200);jsonObjectResult.put("msg", "请求成功");jsonObjectResult.put("data", obj.get("data"));jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}} catch (Exception e) {e.printStackTrace();}return jsonObjectResult.toJSONString();}/*** 上传平台用户信息* @param val* @return*/@Overridepublic R pullUserInfo(String val) {//转换成集合类型JSONArray userListArray = JSONArray.parseArray(val);boolean flag = false;for (Object o : userListArray) {JSONObject jsonObject = (JSONObject) o;User user = new User();//add表示添加//update表示更新//delete表示删除String operate = jsonObject.getString("operate");//固定标识String type = jsonObject.getString("type");JSONObject dataObject = jsonObject.getJSONObject("data");if (type.equals("sso_user")) {Long id = dataObject.getLong("id");//用户账号String account = dataObject.getString("account");//用户名称String name = dataObject.getString("name");//所属部门String departmentId = dataObject.getString("departmentId");//手机号String mobile = dataObject.getString("mobile");//用户角色,1表示管理者,2表示使用者String isManager = dataObject.getString("isManager");//应用编号String project = dataObject.getString("project");//添加用户user.setId(id);user.setPhone(mobile);user.setTenantId("000000");user.setCode("");if(isManager.equals("1")){//管理员user.setRoleId("1529303109787967490");}else if(isManager.equals("2")){//一般用户user.setRoleId("1529302965017370625");}else{//会员(这个地方不会执行到,只要isManager不等于null)user.setRoleId("1355058724514836481");}user.setUserType(Integer.parseInt(isManager));user.setAccount(account);//密码是123456user.setPassword("10470c3b4b1fed12c3baac014be15fac67c6e815");user.setName(name);user.setRealName(name);user.setDeptId(departmentId);user.setStatus(1);//证明是那边过来的用户user.setRemark(type);switch (operate) {case "add":flag = userService.save(user);break;case "update":flag = userService.updateUser(user);break;case "delete":flag = userService.updateById(user);break;default:break;}} else if (type.equals("sso_department")) {Dept dept = new Dept();Long id = dataObject.getLong("id");//用户账号String title = dataObject.getString("title");//父级企业IDString parentId = dataObject.getString("parentId");//企业等级String level = dataObject.getString("level");//排序String sort = dataObject.getString("sort");//用户角色,1表示管理者,2表示使用者String isManager = dataObject.getString("isManager");//业务管路员IDString manager = dataObject.getString("manager");//业务管路员IDString project = dataObject.getString("project");dept.setId(id);dept.setDeptName(title);dept.setTenantId("000000");dept.setParentId(Long.parseLong(parentId));dept.setAncestors("0," + parentId);dept.setDeptCategory(3);dept.setFullName(title);dept.setSort(Integer.parseInt(sort));dept.setRemark(type);dept.setIsDeleted(0);switch (operate) {case "add":flag = deptService.save(dept);break;case "update":flag = deptService.updateById(dept);break;case "delete":flag = deptService.removeDept(id.toString());break;default:break;}}}return R.status(flag);}/*** 退出* @param ssoSessionKey* @return*/@Overridepublic String apiLogout(String ssoSessionKey) {JSONObject jsonObjectResult = new JSONObject();//请求接口地址String url = SsoLoginConstant.APILOGOUT_URL;Map<String, Object> paramMap = new HashMap<String, Object>();paramMap.put("ssoSessionKey", ssoSessionKey);try {String body = HttpUtil.createPost(url).form(paramMap).execute().body();if (StringUtils.isBlank(body)) {jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}JSONObject obj = JSONObject.parseObject(body);if (obj == null) {jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}String code = obj.get("code").toString();if ("200".equals(code)) {jsonObjectResult.put("code", 200);jsonObjectResult.put("msg", "请求成功");jsonObjectResult.put("data", obj.get("data"));jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}else{jsonObjectResult.put("code", 500);jsonObjectResult.put("msg", "请求失败");jsonObjectResult.put("data", "");jsonObjectResult.put("status", false);return jsonObjectResult.toJSONString();}} catch (Exception e) {e.printStackTrace();}return jsonObjectResult.toJSONString();}}

先实现功能,在做优化~

  1. 控制器中的实现方法:
	package org.springblade.modules.system.controller;import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.springblade.common.constant.TrainingSchemeConstant;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.entity.UserService;
import org.springblade.modules.system.service.ISsoLoginService;
import org.springblade.modules.system.service.impl.KnowledgeServiceImpl;
import org.springblade.modules.system.service.impl.SsoLoginServiceImpl;
import org.springblade.modules.system.service.impl.UserServiceImpl;
import org.springblade.modules.system.util.SsoLoginConstant;
import org.springblade.modules.system.util.TokenUtil;
import org.springblade.modules.system.vo.KnowledgeVO;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;import java.util.HashMap;
import java.util.Map;@RestController
@AllArgsConstructor
@RequestMapping("api/sso")
@Api(value = "", tags = "接口")
public class ApiSsoController {private final SsoLoginServiceImpl ssoLoginService;/*** 用户信息*/private final UserServiceImpl userService;//private final RabbitTemplate rabbitTemplate;/*** 统一认证平台向第三方平台的接口发起请求。* 新增、修改、删除平台用户信息,将用户数据上传到我方** @param*/@PostMapping(value = "/pulluserinfo")public String pulluserinfo(@RequestBody String val) {JSONObject object = new JSONObject();R r = ssoLoginService.pullUserInfo(val);if (r.getCode() == 200) {object.put("msg", "操作成功");object.put("success", true);object.put("code", 200);} else {object.put("msg", "操作失败");object.put("success", false);object.put("code", 500);}return object.toJSONString();}/*** 登录鉴权* */@GetMapping("/check_login")public R checkLogin(String ssoSessionKey) {//拿到接口返回值String result = ssoLoginService.checkLogin(ssoSessionKey);JSONObject jsonObject = JSON.parseObject(result);Integer code = jsonObject.getInteger("code");if (code == 200) {//操作成功JSONObject jsonObjectData = jsonObject.getJSONObject("data");//拿到用户名和密码if (jsonObjectData != null) {//将用户名传给前台,前台拿着去登陆去String account = jsonObjectData.getString("username");return R.data(account);} else {return R.fail("未找到该用户");}} else {//操作失败return R.fail("未找到该用户");}}/*** 查询平台用户信息* */@GetMapping("/get_user")public String getUser(String projectKey) {return ssoLoginService.getUser(projectKey);}/*** 查询平台组织机构* */@GetMapping("/get_department")public String getDepartment(String projectKey) {return ssoLoginService.getDepartment(projectKey);}/*** 退出时调用* 注销统一认证平台的用户信息*/@GetMapping("/api_logout")public R apiLogout(String ssoSessionKey) {//拿到接口返回值String result = ssoLoginService.apiLogout(ssoSessionKey);JSONObject jsonObject = JSON.parseObject(result);Integer code = jsonObject.getInteger("code");if (code == 200) {return R.success("操作成功");} else {//操作失败return R.fail("接口请求出错");}}}

整个后台的代码基本上就这些,基本上没啥难度,就是光操作的调用接口就可以了,主要麻烦点的是在前端,明天分享一下前端的实现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323619.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学习ASP.NET Core,怎能不了解请求处理管道[1]: 中间件究竟是个什么东西?

ASP.NET Core管道虽然在结构组成上显得非常简单&#xff0c;但是在具体实现上却涉及到太多的对象&#xff0c;所以我们在 “通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程”&#xff08;上篇、中篇、下篇&#xff09; 中围绕着一个经过极度简化的模拟管道讲述…

POJ2689-Prime Distance【质数,数论】

正题 题目链接:http://poj.org/problem?id2689 题目大意 求闭区间[L,R][L,R]中相邻的最远和最近的两个质数。 解题思路 我们可以用前R−−√个质因子筛这个区间内的质数R个质因子筛这个区间内的质数解题思路 #include<cstdio> #include<algorithm> #include&l…

for循环(三)

利用for循环打出乘法口诀表 #include<stdio.h>main(){int i,j,k;for(i1;i<10;i){for(j1;j<i1;j){printf("%d*%d%d\t",i,j,ki*j); }printf("\n");} } ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190324224732816.png?x-oss-proce…

springboot实现用户统一认证、管理

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”前言现在是&#xff1a;2022年5月25日13:44:16最近和模拟登录杠上了&#xff0c;这不&#xff0c;又来了个需求&#xff0c;还是以这个技术点入手的。需求大概是这样的&#xff1a;为了统…

Mybatis 使用的 9 种设计模式,真是太有用了

转载自 Mybatis 使用的 9 种设计模式&#xff0c;真是太有用了 虽然我们都知道有26个设计模式&#xff0c;但是大多停留在概念层面&#xff0c;真实开发中很少遇到&#xff0c;Mybatis源码中使用了大量的设计模式&#xff0c;阅读源码并观察设计模式在其中的应用&#xff0c;…

P1463-[POI2002][HAOI2007]反素数【约数,数论】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP1463 题目大意 求1∼n1∼n中最大的一个约数个数比前面的所有数都要多的数。 解题思路 首先根据数据我们可以得知这个数的质因子不超过10个。而且这个数的质因子是连续若干个最小的质数&#xff0c;而…

springboot实现用户统一认证、管理-前端实现

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 前言 现在是&#xff1a;2022年6月2日15:43:51 上篇文章讲述了springboot中实现用户统一认证的具体内容&#xff0c;主要从后端角度出发的&#xff0c;其实大部分功能还是前端与后端交互的…

for循环(四)

利用for循环打出任意金字塔层数 #include<stdio.h>main(){int i,j,k,ceng;printf("请输入金字塔层数"); scanf("%d",&ceng);for(i1;i<ceng;i){for(j1;j<ceng-i1;j){printf(" ");}for(k1;k<i;k){printf(" *");}pri…

Unity3damp;amp;C#分布式游戏服务器ET框架介绍-组件式设计

前几天写了《开源分享 Unity3d客户端与C#分布式服务端游戏框架》&#xff0c;受到很多人关注&#xff0c;QQ群几天就加了80多个人。开源这个框架的主要目的也是分享自己设计ET的一些想法&#xff0c;所以我准备写一系列的文章&#xff0c;介绍下自己的思路跟设计&#xff0c;每…

springboot+vue实现用户统一认证、管理-前端实现

“大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂”前言现在是&#xff1a;2022年6月2日15:43:51上篇文章讲述了springboot中实现用户统一认证的具体内容&#xff0c;主要从后端角度出发的&#xff0c;其实大部分功能还是前端与后端交互的…

JS中 [] == ![]结果为true,而 {} == !{}却为false, 追根刨底

转载自 JS中 [] ![]结果为true&#xff0c;而 {} !{}却为false&#xff0c; 追根刨底 console.log( [] ![] ) // true console.log( {} !{} ) // false 在比较字符串、数值和布尔值的相等性时&#xff0c;问题还比较简单。但在涉及到对象的比较时&#xff0c;问题就变…

P2261-[CQOI2007]余数求和【数论,约数】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP2261 题目大意 求∑i1nk%i\sum^{n}_{i1}k\%i∑i1n​k%i。 解题思路 将k%ik\%ik%i展开一下&#xff0c;k−i∗⌊k/i⌋k-i*\lfloor k/i\rfloork−i∗⌊k/i⌋&#xff0c;然后答案就是 ∑i1nk−i∗⌊k/…

Centos7 amp;amp; Docker amp;amp; Jenkins amp;amp; ASP.NET Core

写在前面 Docker一直很火热&#xff0c;一直想把原本的Jenkins自动部署工具搬到Docker上面&#xff0c;无奈今年一直忙于各种事情&#xff0c;迟迟未实施这个事情&#xff0c;正好迎来了dotnet core 2.0 的正式发布&#xff0c;升级项目的同时&#xff0c;顺便直接将Jenkins搬到…

国民体质测定标准手册及标准解析成JSON文件计算分数,java解析excel文件

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂 前言 现在是&#xff1a;2022年6月14日10:07:27 最近在做体质测评的功能&#xff0c;需要依据《国民体质测定标准手册及标准》&#xff0c;根据用户的个人信息&#xff0c;从而计算出各个…

getchar与putchar用法

#include<stdio.h>main(){int i;igetchar();//相当于char i;scanf("%c",&i); putchar(i);//相当于printf("%c",i); 需要i是字符才能输出不能是变量printf("\n");printf("%d",i);}输出结果一致 #include<stdio.h>main…

TCP为什么是三次握手和四次挥手

转载自 TCP为什么是三次握手和四次挥手 为什么建立连接是三次握手断开连接是四次挥手&#xff1f; 三次握手的流程和四次挥手的流程是什么&#xff1f; 三次握手与四次回收分别对应TCP连接与断开过程 tcp报文格式 标志位含义 ACK&#xff1a;确认序号有效。 SYN&#x…

P1072-Hankson的趣味题【数论,gcd】

正题 评测记录:https://www.luogu.org/recordnew/lists?uid52918&pidP1072 题目大意 a1gcd(a0,x)a1gcd(a0,x)b1gcd(b0,x)b1gcd(b0,x)求xx解题思路如果 a1=gcd(a0,x)" role="presentation">a1=gcd(a0,x)a1=gcd(a0,x) 所以xka∗a1xka∗a1b1gcd(b0,x)b1g…

HTM文件中使用vue

大家好&#xff0c;我是雄雄&#xff0c;欢迎关注微信公众号&#xff1a;雄雄的小课堂。 代码啊&#xff0c;尤其是比较重要客户的项目&#xff0c;即使包出去了&#xff0c;代码也一定要回到自己手里&#xff0c;不然干着急。 这个项目&#xff0c;已经经过两手了&#xff0c…

LVS三种模式的区别及负载均衡算法

转载自 LVS三种模式的区别及负载均衡算法 LVS简介 LVS&#xff08;Linux Virtual Server&#xff09;即Linux虚拟服务器&#xff0c;是一个虚拟的服务器集群系统&#xff0c;由章文嵩博士在1998年5月成立&#xff0c;在linux2.6后将lvs自动加入了kernel模块&#xff0c;我们…

POJ3696-The Luckiest number【数论,欧拉定理】

正题 题目链接:http://poj.org/problem?id3696 题目大意 求多少个8连在一起是LL的倍数。解题思路将x个8连在一起分解一下 10x&#x2212;19" role="presentation">10x−1910x−19 那么就是 L|2∗(10x−1)9L|2∗(10x−1)9dgcd(L,8)dgcd(L,8)分解一下 9…