Session与Cookie(自定义Session)
一、会话管理
会话管理: 管理浏览器客户端 和 服务器端之间会话过程中产生的会话数据。
域对象: 实现资源之间的数据共享。
request域对象
context域对象
会话技术:
Cookie技术:会话数据保存在浏览器客户端。
Session技术:会话数据保存在服务器端。存放在内存里面,客户端与服务器端之前的通讯使用SessionId
二、Cookie技术
2.1 特点:Cookie技术:会话数据保存在浏览器客户端。
2.2 Cookie技术核心
Cookie类:用于存储会话数据
1)构造Cookie对象
New Cookie(java.lang.String name, java.lang.String value)
2)设置cookie
void setPath(java.lang.String uri) :设置cookie的有效访问路径
void setMaxAge(int expiry) : 设置cookie的有效时间
void setValue(java.lang.String newValue) :设置cookie的值
3)发送cookie到浏览器端保存
void response.addCookie(Cookie cookie) : 发送cookie
4)服务器接收cookie
Cookie[] request.getCookies() : 接收cookie
2.3 Cookie原理
1)服务器创建cookie对象,把会话数据存储到cookie对象中。
new Cookie("name","value");
2) 服务器发送cookie信息到浏览器
response.addCookie(cookie);
举例: set-cookie: name=eric (隐藏发送了一个set-cookie名称的响应头)
3)浏览器得到服务器发送的cookie,然后保存在浏览器端。
4)浏览器在下次访问服务器时,会带着cookie信息
举例: cookie: name=eric (隐藏带着一个叫cookie名称的请求头)
5)服务器接收到浏览器带来的cookie信息
request.getCookies();
2.4 Coolie的细节
1)void setPath(java.lang.String uri) :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。
2)void setMaxAge(int expiry) : 设置cookie的有效时间。
正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。
负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!
零:表示删除同名的cookie数据
3)Cookie数据类型只能保存非中文字符串类型的。可以保存多个cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
2.5 Cookie 问题
1) cookie不能跨浏览器
2)浏览器关闭,默认失效cookie
3)127.0.0.1和localhost,操作cookie时不共享
2.6 Cookie的局限:
1)Cookie只能存字符串类型,不能保存对象
2)只能存非中文
3)1个cookie的容量不超过4KB
2.7 案例-显示用户上次访问时间
@WebServlet("/LastAccessTime")
public class LastAccessTime extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");// 防止浏览器显示乱码
String lastAccessTime = null;
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
String name = cookie.getName();
if (name.equals("lastAccessTime")) {
lastAccessTime = cookie.getValue();
break;
}
}
if (StringUtils.isEmpty(lastAccessTime)) {
resp.getWriter().print("您是首次访问!");
} else {
resp.getWriter().print("你上次访问时间:" + lastAccessTime);
}
// 保存访问时间
// 创建cookie 将当前时间作为cookie保存到浏览器
String currenttime = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(new Date());
Cookie cookie = new Cookie("lastAccessTime", currenttime);
cookie.setMaxAge(60 * 60 * 24);
// 发送cookie
resp.addCookie(cookie);
}
String addCookie(String key, String value, HttpServletResponse resp) {
return key;
}
}
三、Session技术
3.1 由于Cookie的局限性和问题,想要突破这些限制只能使用session技术!
Session特点:会话数据保存在服务器端。(内存中)
3.2 Session 技术核心
HTTPSession类:用于保存会话数据
1)创建或得到session对象
HttpSession getSession()
HttpSession getSession(boolean create) //true,没有session,会创建。False则不会创建
2)设置session对象
void setMaxInactiveInterval(int interval) : 设置session的有效时间
void invalidate() : 销毁session对象
java.lang.String getId() : 得到session编号
3)保存会话数据到session对象
void setAttribute(java.lang.String name, java.lang.Object value) : 保存数据
java.lang.Object getAttribute(java.lang.String name) : 获取数据
void removeAttribute(java.lang.String name) : 清除数据
3.3 Session原理
服务器端创建session,通过响应头将sessionId保存到客户端本地。客户端通过请求头,将sessionId传递到服务器端。
关闭浏览器只会清楚客户端的sessionID,服务器端的session由创建时的时间失效决定。
代码解读:HttpSession session = request.getSession();
1)第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID
new HttpSession();
2)把JSESSIONID作为Cookie的值发送给浏览器保存
Cookie cookie = new Cookie("JSESSIONID", sessionID);
response.addCookie(cookie);
3)第二次访问的时候,浏览器带着JSESSIONID的cookie访问服务器
4)服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象。
if(找到){
return map.get(sessionID);
}else{
new HttpSession();
}
5)如果找到对应编号的session对象,直接返回该对象
6)如果找不到对应编号的session对象,创建新的session对象,继续走1的流程
结论:通过JSESSION的cookie值在服务器找session对象!
3.4 Session细节
1)java.lang.String getId() : 得到session编号
2)两个getSession方法:
getSession(true) / getSession() : 创建或得到session对象。没有匹配的session编号,自动创建新的session对象。
getSession(false): 得到session对象。没有匹配的session编号,返回null
3)void setMaxInactiveInterval(int interval) : 设置session的有效时间
session对象销毁时间:
3.1 默认情况30分服务器自动回收
3.2 修改session回收时间
3.3 全局修改session有效时间
<!-- 修改session全局有效时间:分钟 -->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
3.4.手动销毁session对象
void invalidate() : 销毁session对象
4)如何避免浏览器的JSESSIONID的cookie随着浏览器关闭而丢失的问题
/**
* 手动发送一个硬盘保存的cookie给浏览器
*/
Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
总结:
1)会话管理: 浏览器和服务器会话过程中的产生的会话数据的管理。
2)Cookie技术:
new Cookie("name","value")
response.addCookie(coookie)
request.getCookies()
3)Session技术
request.getSession();
setAttrbute("name","会话数据");
getAttribute("会话数据")
四、自定义缓存
4.1定义缓存实体类
public class Cache {
public Cache(String key, Object value, Long timeOut) {
super();
this.key = key;
this.value = value;
this.timeOut = timeOut;
}
public Cache() {
}
/**
* key
*/
private String key;
/**
* 缓存数据
*/
private Object value;
/**
* 超时时间
*/
private Long timeOut;
}
4.2 定义缓存类
/**
* @classDesc: 功能描述:(缓存map)
*/
public class CacheManager {
private Map<String, Cache> cacheMap = new HashMap<>();
/**
* @methodDesc: 功能描述:(往缓存存值)
*/
public void put(String key, Object oj) {
put(key, oj, null);
}
/**
* @methodDesc: 功能描述:(往缓存存值)
*/
public synchronized void put(String key, Object oj, Long timeOut) {
if (oj == null) {
return;
}
Cache cache = new Cache();
cache.setKey(key);
if (timeOut != null)
cache.setTimeOut(timeOut + System.currentTimeMillis());
cache.setValue(oj);
cacheMap.put(key, cache);
}
/**
* @methodDesc: 功能描述:(删除)
*/
public synchronized void deleteCache(String key) {
cacheMap.remove(key);
}
/**
* @methodDesc: 功能描述:(获取缓存中数据)
*/
public synchronized Object get(String key) {
Cache cache = cacheMap.get(key);
Object oj = null;
if (cache != null) {
oj = cache.getValue();
}
return oj;
}
/**
* @methodDesc: 功能描述:(检查数据是否在有效期内)
*/
public synchronized void checkValidityData() {
for (String key : cacheMap.keySet()) {
Cache cache = cacheMap.get(key);
Long timeOut = cache.getTimeOut();
if (timeOut == null) {
return;
}
long currentTime = System.currentTimeMillis();
long endTime = timeOut;
long result = (currentTime - endTime);
if (result > 0) {
System.out.println("清除:"+key);
cacheMap.remove(key);
}
}
}
public static void main(String[] args) throws InterruptedException {
CacheManager cacheManager = new CacheManager();
// cacheManager.put("lisi", 0);
cacheManager.put("zhangsan", "jj", 5000l);
// 多线程,验证session的有效时间
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
scheduledThreadPool.schedule(new Runnable() {
public void run() {
cacheManager.checkValidityData();
}
}, 5000, TimeUnit.MILLISECONDS);
Thread.sleep(5000);
System.out.println(cacheManager.get("zhangsan"));
}
}
五、自定义Token
5.1 什么是token
token其实就是一个令牌,具有随机性,类似于sessionId。在对接一些第三方平台的时候,为了能够保证数据安全性,通常会使用一些令牌进行交互。
5.2 如何自定义token
token生成规则,只要保证token生成一个不重复的唯一字符串即可。使用jdk自带的uuid生成规则。
5.3 什么是UUID
UUID含义是通用唯一识别码 (Universally Unique Identifier),这是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OSF) 的组织应用在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部分。
UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。如此一来,每个人都可以建立不与其它人冲突的 UUID。
5.4 UUID的组成
UUID保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成的API。按照开放软件基金会(OSF)制定的标准计算,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字
UUID由以下几部分的组合:
(1)当前日期和时间,UUID的第一个部分与时间有关,如果你在生成一个UUID之后,过几秒又生成一个UUID,则第一个部分不同,其余相同。
(2)时钟序列。
(3)全局唯一的IEEE机器识别号,如果有网卡,从网卡MAC地址获得,没有网卡以其他方式获得。
UUID的唯一缺陷在于生成的结果串会比较长。关于UUID这个标准使用最普遍的是微软的GUID(Globals Unique Identifiers)。在ColdFusion中可以用CreateUUID()函数很简单地生成UUID,其格式为:xxxxxxxx-xxxx-
xxxx-xxxxxxxxxxxxxxxx(8-4-4-16),其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。而标准的UUID格式为:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
(8-4-4-4-12)。
5.5 UUID代码
UUID。randomUUID().toString()
六、表单重复提交解决方案(防止http重复提交)
6.1 场景描述:
网络延时:在平时开发中,如果网速比较慢的情况下,用户提交表单后,发现服务器半天都没有响应,那么用户可能会以为是自己没有提交表单,就会再点击提交按钮重复提交表单,我们在开发中必须防止表单重复提交。
重复刷新:表单提交后用户点击【刷新】按钮导致表单重复提交。
后退再提交:点击浏览器的【后退】按钮回退到表单页面后进行再次提交
6.2 解决方案
6.2.1 使用javascript 解决
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Form表单</title>
<script type="text/javascript">
var isFlag = false; //表单是否已经提交标识,默认为false
function submitFlag() {
if (isFlag == false) {
isFlag = true;
return true;
} else {
return false;
}
}
</script>
</head>
<body>
<form action="${pageContext.request.contextPath}/DoFormServlet"
method="post" onsubmit="return submitFlag()">
用户名:<input type="text" name="userName"> <input type="submit"
value="提交" id="submit">
</form>
</body>
</html>
6.2.2 使用后端提交解决
对于【重复刷新】、【后退再提交】导致表单重复提交的问题,前端无法解决,只能在服务器端解决。
在服务器端生成一个唯一的随机标识号,专业术语称为Token(令牌),同时在当前用户的Session域中保存这个Token。然后将Token发送到客户端的Form表单中,在Form表单中使用隐藏域来存储这个Token,表单提交的时候连同这个Token一起提交到服务器端,然后在服务器端判断客户端提交上来的Token与服务器端生成的Token是否一致,如果不一致,那就是重复提交了,此时服务器端就可以不处理重复提交的表单。如果相同则处理表单提交,处理完后清除当前用户的Session域中存储的标识号。
在下列情况下,服务器端将拒绝处理用户提交的表单请求:
- 存储Session域中的Token(令牌)与表单提交的Token(令牌)不同。
- 当前用户的Session中不存在Token(令牌)。
- 用户提交的表单数据中没有Token(令牌)。
转发代码:
@WebServlet("/ForwardServlet")
public class ForwardServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().setAttribute("sesionToken", TokenUtils.getToken());
req.getRequestDispatcher("form.jsp").forward(req, resp);
}
}
转发页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Form表单</title> </head> <body>
<form action="${pageContext.request.contextPath}/DoFormServlet"
method="post" onsubmit="return dosubmit()">
<input type="hidden" name="token" value="${sesionToken}"> 用户名:<input type="text"
name="userName"> <input type="submit" value="提交" id="submit">
</form>
</body>
</html>
后端代码:
@WebServlet("/DoFormServlet")
public class DoFormServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
boolean flag = isFlag(req);
if (!flag) {
resp.getWriter().write("已经提交...");
System.out.println("数据已经提交了..");
return;
}
String userName = req.getParameter("userName");
try {
Thread.sleep(300);
} catch (Exception e) {
}
System.out.println("往数据库插入数据...." + userName);
resp.getWriter().write("success");
} public boolean isFlag(HttpServletRequest request) {
HttpSession session = request.getSession();
String sesionToken = (String) session.getAttribute("sesionToken");
String token = request.getParameter("token");
if (!(token.equals(sesionToken))) {
return false;
}
session.removeAttribute("sesionToken");
return true;
}
}
七、Servlet之Filter
7.1 什么是Filter
Filter 也称之为过滤器,它是 Servlet 技术中最实用的技术,Web 开发人员通过 Filter 技术,对 web 服务器管理的所有 web 资源:例如 Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现 URL 级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
它主要用于对用户请求进行预处理,也可以对 HttpServletResponse 进行后处理。使用 Filter 的完整流程:Filter 对用户请求进行预处理,接着将请求交给 Servlet 进行处理并生成响应,最后 Filter 再对服务器响应进行后处理。
7.2 Fileter使用
import java.io.IOException;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 使用Filter 打印参数
*
*/
public class FilterDemo implements Filter {
public FilterDemo(){
System.out.println("FilterDemo 构造函数被执行...");
}
/**
* 销毁
*/
public void destroy() {
System.out.println("destroy");
}
public void doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse,
FilterChain paramFilterChain) throws IOException, ServletException {
System.out.println("doFilter");
HttpServletRequest request = (HttpServletRequest) paramServletRequest;
HttpServletResponse response = (HttpServletResponse) paramServletResponse;
// 请求地址
String requestURI = request.getRequestURI();
System.out.println("requestURI:"+requestURI);
// 参数
Map<String, String[]> parameterMap = request.getParameterMap();
for (String key : parameterMap.keySet()) {
String[] arr=parameterMap.get(key);
}
}
/**
* 初始化
*/
public void init(FilterConfig paramFilterConfig) throws ServletException {
System.out.println("init");
}
}
web.xml配置
<filter>
<filter-name>FilterDemo</filter-name>
<filter-class>com.stu.servlet.FilterDemo</filter-class>
</filter>
<filter-mapping>
<filter-name>FilterDemo</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
7.3 使用Filter防止XSS攻击
7.3.1 什么是XSS攻击
XSS攻击使用Javascript脚本注入进行攻击,例如在表单中注入: <script>location.href='http://www.baidu.com'</script>
fromToXss.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="XssDemo" method="post">
<input type="text" name="userName"> <input type="submit">
</form>
</body>
</html>
import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet("/XssDemo")
public class XssDemo extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userName = req.getParameter("userName");
req.setAttribute("userName", userName);
req.getRequestDispatcher("showUserName.jsp").forward(req, resp);
}
}
show.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>userName:${userName}
</body>
</html>
73..2 解决方案:使用Filter过滤器过滤注入标签
import java.io.IOException;
import java.util.Map; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class FilterDemo implements Filter {
public FilterDemo() {
System.out.println("FilterDemo 构造函数被执行...");
}
/**
* 销毁
*/
public void destroy() {
System.out.println("destroy");
}
public void doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse,
FilterChain paramFilterChain) throws IOException, ServletException {
System.out.println("doFilter");
HttpServletRequest request = (HttpServletRequest) paramServletRequest;
XssAndSqlHttpServletRequestWrapper xssRequestWrapper = new XssAndSqlHttpServletRequestWrapper(request);
// HttpServletResponse response = (HttpServletResponse)
// paramServletResponse;
// // 请求地址
// String requestURI = request.getRequestURI();
// System.out.println("requestURI:" + requestURI);
// // 参数
// Map<String, String[]> parameterMap = request.getParameterMap();
// for (String key : parameterMap.keySet()) {
// String[] arr = parameterMap.get(key);
// System.out.print("key:");
// for (String string : arr) {
// System.out.println(string);
// }
// }
paramFilterChain.doFilter(xssRequestWrapper, paramServletResponse);
}
/**
* 初始化
*/
public void init(FilterConfig paramFilterConfig) throws ServletException {
System.out.println("init");
}
}
XssAndSqlHttpServletRequestWrapper
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils; /**
* 防止XSS攻击
*/
public class XssAndSqlHttpServletRequestWrapper extends HttpServletRequestWrapper {
HttpServletRequest request;
public XssAndSqlHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
this.request = request;
}
public String getParameter(String name) {
String value = request.getParameter(name);
System.out.println("name:" + name + "," + value);
if (!StringUtils.isEmpty(value)) {
// 转换Html
value = StringEscapeUtils.escapeHtml4(value);
}
return value;
}
}
Session与Cookie(自定义Session)的更多相关文章
- 【荐】PHP Session和Cookie,Session阻塞,Session垃圾回收,Redis共享Session,不推荐Memcached保存Session
什么是 Session 在 web 应用开发中,Session 被称为会话.主要被用于保存某个访问者的数据. 由于 HTTP 无状态的特点,服务端是不会记住客户端的,对服务端来说,每一个请求都是全新的 ...
- 牛客网Java刷题知识点之什么是cookie、什么是session、cookie和session有什么区别
不多说,直接上干货! https://www.nowcoder.com/ta/review-java/review?tpId=31&tqId=21170&query=&asc= ...
- Django - Cookie、Session、自定义分页和Django分页器
2. 今日内容 https://www.cnblogs.com/liwenzhou/p/8343243.html 1. Cookie和Session 1. Cookie 服务端: 1. 生成字符串 2 ...
- Tornado-Secure cookie and Session
这一节涉及的内容有: 1.客户端和服务端操作cookie的方法 2.secure cookie的机制 3.基本/自定义session 文件结构 三个启动文件由下往上对应的分别是三种服务端:使用secu ...
- Django:Admin,Cookie,Session
一. Admin的配置 1.Admin基础设置 admin是django强大功能之一,它能够从数据库中读取数据,呈现在页面中,进行管理.默认情况下,它的功能已经非常强大,如果你不需要复杂的功能,它已经 ...
- Session、Cookie与Token
http协议是无状态协议 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到 ...
- Cookie与Session的区别-总结很好的文章
Cookie与Session的区别-总结很好的文章 本文分别对Cookie与Session做一个介绍和总结,并分别对两个知识点进行对比分析,让大家对Cookie和Session有一个更深入的了解,并对 ...
- Cookie与Session的区别
cookie机制 Cookies是服务器在本地机器上存储的小段文本并随每一个请求发送至同一个服务器.IETF RFC 2965 HTTP State Management Mechanism 是通用c ...
- Session与Cookie
Session与Cookie的比较 Cookie与Session都可以进行会话跟踪,但是实现的原理不太一样.一般情况下二者均可以满足需求,但有时候不可以使用Cookie,有时候不可以使用Session ...
随机推荐
- 基于mapreduce实现图的三角形计数
源代码放在我的github上,想细致了解的可以访问:TriangleCount on github 一.实验要求 1.1 实验背景 图的三角形计数问题是一个基本的图计算问题,是很多复杂 ...
- dubbo不完全指南
Dubbo架构 节点角色说明 节点 角色说明 Provider 暴露服务的服务提供方 Consumer 调用远程服务的服务消费方 Registry 服务注册与发现的注册中心 Monitor 统计服务的 ...
- 痞子衡嵌入式:第一本Git命令教程(0)- 索引
大家好,我是痞子衡,是正经搞技术的痞子.本系列痞子衡给大家讲的是Git命令汇编,共12篇文章,循序渐进地介绍Git操作的完整过程. 在开始Git课程之前,需要先跟大家普及2个重要概念(四度空间.四种状 ...
- Mac实用技巧之:访达/Finder
更多Mac实用技巧系列文章请访问我的博客:Mac实用技巧系列文章 Finder就相当于windows XP系统的『我的电脑』或win7/win10系统里的『计算机』(打开后叫资源管理器),find是查 ...
- 🧬 C# 神经网络计算库和问题求解
Andrew Kirillov 著 Conmajia 译 2019 年 1 月 12 日 原文发表于 CodeProject(2006 年 11 月 19 日),已获作者本人授权. 本文介绍了一个用于 ...
- PLSQL 登录出现 ora12638 credential retrieval failed
参考:http://blog.csdn.net/yjq8116/article/details/4203168 解决了 开始 -> 程序 -> Oracle -> Configura ...
- 【学习笔记】分布式Tensorflow
目录 分布式原理 单机多卡 多机多卡(分布式) 分布式的架构 节点之间的关系 分布式的模式 数据并行 同步更新和异步更新 分布式API 分布式案例 Tensorflow的一个特色就是分布式计算.分布式 ...
- nginx系列12:一致性哈希算法
前面一节的hash算法存在一个问题,当上游的应用服务器因某一台down掉导致服务器数量发生变化时,会导致大量的请求路由策略失效,一致性哈希算法可以缓解这个问题. 一致性哈希算法 1,hash算法存在的 ...
- MySQL 字符集和校对
字符集是指一种从二进制编码到某类字符符号的映射,校对是一组用于某个字符集的排序规则.每一类编码字符都有其对应的字符集和校对规则 MySQL 如何使用字符集 每种字符集都可能有多种校对规则,并且都有一个 ...
- Odoo 中使用 celery 实现高性能异步任务队列
详见:http://www.oejia.net/blog/2018/07/09/odoo_task_queue.html 概述 在 odoo 中可以用自带的cron实现异步任务,这个cron基于多线程 ...