利用frp工具实现内网穿透、随时随地访问内网服务

前言

之前分享过一次《ZeroTier实现内网穿透、异地组网》,其基本工作原理是组建一个虚拟局域网,各个设备(NAS、Linux、Windows、Mac、iOS、Android)安装了客户端、加入到这个虚拟局域网后,就会自动分配一个IP,从而实现局域网内各个设备及服务的相互访问。

而今天要介绍的内网穿透工具是frp,与ZeroTier不同的是,frp无需在各个终端设备上安装客户端,只需要在具有公网 IP 的节点上部署 frp 服务端,即可轻松地将内网服务穿透到公网,从而实现随时随地访问内网服务。

一、frp简介

1.frp是什么

frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。

项目地址:https://github.com/fatedier/frp/releases 中文文档:https://gofrp.org/docs/overview/

2.为什么使用 frp ?

通过在具有公网 IP 的节点上部署 frp 服务端,可以轻松地将内网服务穿透到公网,同时提供诸多专业的功能特性,这包括:

  • 客户端服务端通信支持 TCP、KCP 以及 Websocket 等多种协议。
  • 采用 TCP 连接流式复用,在单个连接间承载更多请求,节省连接建立时间。
  • 代理组间的负载均衡。
  • 端口复用,多个服务通过同一个服务端端口暴露。
  • 多个原生支持的客户端插件(静态文件查看,HTTP、SOCK5 代理等),便于独立使用 frp 客户端完成某些工作。
  • 高度扩展性的服务端插件系统,方便结合自身需求进行功能扩展。
  • 服务端和客户端 UI 页面。

3.基本原理

基本工作原理如上图所示:

  • 在带有公网ip的云服务器上部署frp的服务端frps;
  • 在需要穿透的内网服务器上部署frp的客户端frpc;
  • 每个客户端都会有一个配置文件用于和服务器连接,不同的内网服务配置不同的端口号,例如内网服务器A上安装了jira服务,其端口是8080,内网服务器B上安装了Gitlab服务,其端口号是8081;
  • 用户通过访问公网ip+端口号,公网服务器此时就相当于代理服务器,上面部署的frps服务端会根据端口号,自动转发到对应的内网服务器上,从而访问到内网服务;

二、前置环境准备

服务端和客户端使用的都是同一份文件,只是配置文件和启动文件不同。因此只需要下载一份文件,将其上传到各个服务器即可。

1.下载解压

下载地址:

https://github.com/fatedier/frp/releases

解压:

tar -xvf frp_0.44.0_linux_amd64.tar.gz  # 解压缩
mv frp_0.44.0_linux_amd64 frp  # 重命名文件夹为frp

2.目录解读

  • frpc:客户端可执行程序
  • frpc_full.ini:客户端所有配置项(可以在此文件查看frp的所有的配置项)
  • frpc.ini:客户端配置项
  • frps:服务端可执行程序
  • frps_full.ini:服务端所有配置项(可以在此文件查看frp的所有的配置项)
  • frps.ini:服务端配置项
  • LICENSE:许可证

三、服务端配置

服务端需部署在带有公网ip的服务器上,最好是云服务器。frp对于云服务器的配置要求不高,类似2C2G的入门级云服务器即可。而且目前各大厂商都在搞活动,入门级云服务器一年才50元左右。

1.配置服务端

为避免误操作,可以删除客户端相关的文件及配置

rm -fr frpc*  # 删除所有客户端相关的文件及配置
cp frpc.ini frpc.ini.bak  # 备份原始配置文件

编辑配置文件:frps.ini

[common]
# frp监听的端口,默认是7000,可以改成其他的
bind_port = 7000
# 授权码,请改成更复杂的,这个token之后在客户端会用到
token = e10adc3949ba59abbe56e057f20f883e
# 开启HTTP
#vhost_http_port = 8088
# 去除TCP速度限制
tcp_mux = false

# frp管理后台端口,请按自己需求更改
dashboard_port = 7500
# frp管理后台用户名和密码,请改成自己的
dashboard_user = admin
dashboard_pwd = admin123456
enable_prometheus = true

# frp日志配置
log_file = /home/frp/frp/frps.log
log_level = info
log_max_days = 3
./frps -c frps.ini  # 启动服务端

2.开通安全组

若公网服务器是在阿里云、百度云等云服务器上的,则需要在安全组中为frp开通指定的端口号,如:7000是frp服务默认端口号、7500是在frps.ini配置文件中指定的dashboard_port、其他的则是需要映射到内网服务器的端口

3.访问dashboard

访问地址:http://180.xxx.xxx.xxx:7500

账号密码:admin、admin123456(对应配置文件中的dashboard_user与dashboard_pwd)

4.将frps添加为本地服务(可选)

也可以将frps添加为本地服务,具体步骤如下:

① 服务端新建文件:frps.service

内容如下:

[Unit]
Description=frps service
After=network.target syslog.target
Wants=network.target

[Service]
Type=simple
ExecStart=/home/frp/frp/frps -c /home/frp/frp/frps.ini

[Install]
WantedBy=multi-user.target

② 创建配置文件目录并复制文件

mkdir -p /etc/frp
cp frps.ini /etc/frp/
cp frps /usr/bin/
cp frps.service /usr/lib/systemd/system/

③ 配置自并启动客户端服务

systemctl enable frps  # 允许自启动
# 执行成功会提示“Created symlink /etc/systemd/system/multi-user.target.wants/frps.service → /usr/lib/systemd/system/frps.service.”
systemctl start frps  # 启动客户端服务

若更改了frps.service,则需使用“systemctl daemon-reload”命令重新加载配置。

三、客户端配置

1.编辑客户端配置文件

[common]
server_addr = 180.xxx.xxx.xxx  # 服务端所在的公网ip地址
server_port = 7000  # 服务端默认端口号,与服务端配置文件保持一致
token = e10adc3949ba59abbe56e057f20f883e
# 去掉速度限制
tcp_mux = false

[jira]
type = tcp # 注意:这个地方一律填写tcp
local_ip = 192.168.1.211  # jira所在内网服务器的ip地址
local_port = 8088 # 本地访问端口号
remote_port = 8088 # 映射到云服务器的端口号

[gitlab]
type = tcp # 注意:这个地方一律填写tcp
local_ip = 192.168.1.211  # gitlab所在内网服务器的ip地址
local_port = 8081 # 本地访问端口号
remote_port = 8081 # 映射到云服务器的端口号

2.启动客户端

./frpc -c frpc.ini # 启动客户端

3.云服务器安全组添加端口号

安全组中添加remote_port端口号

4.访问HTTP服务

此时则可以通过公网IP+内网端口访问指定服务,如下图所示,访问的是内网服务器的jira服务。

5.查看dashboard连接记录

客户端启动成功,通过代理访问后,可以看到dashboard的Proxies-TCP中记录了连接信息:

6.将frpc服务加为本地服务(可选)

① 客户端新建文件:frpc.service

内容如下:

[Unit]
Description=frpc service
After=network.target syslog.target
Wants=network.target

[Service]
Type=simple
ExecStart=/home/frp/frpc -c /home/frp/frpc.ini

[Install]
WantedBy=multi-user.target

② 创建配置文件目录并复制文件

mkdir -p /etc/frp
cp frpc.ini /etc/frp/
cp frpc /usr/bin/
cp frpc.service /usr/lib/systemd/system/

③ 配置自并启动客户端服务

systemctl enable frpc  # 允许自启动
# 执行成功会提示“Created symlink from /etc/systemd/system/multi-user.target.wants/frpc.service to /usr/lib/systemd/system/frpc.service.”
systemctl start frpc  # 启动客户端服务

若更改了frps.service,则需使用“systemctl daemon-reload”命令重新加载配置。

四、常见问题及解决

1.客户端配置http转发启动服务报错

若在客户端配置文件中配置了http转发,启动客户端服务时发生如下报错:

【原因】:服务端配置文件frps.ini中未配置vhost_http_port

【解决办法】:

① 服务端配置文件frps.ini的[common]中添加vhost_http_port

[common]
# frp监听的端口,默认是7000,可以改成其他的
bind_port = 7000
# 授权码,请改成更复杂的,这个token之后在客户端会用到
token = e10adc3949ba59abbe56e057f20f883e
# 开启HTTP
vhost_http_port = 8088

② 客户端配置文件frpc.ini中添加custom_domains

[web]
type = http
local_ip = 192.168.1.211  # 内网本机ip
local_port = 8088  # 本地服务端口号
remote_port = 8088  # 映射到的公网服务器端口号
custom_domains = 服务端所在的公网ip

③ 配置后重新启动客户端服务

./frpc -c frpc.ini

注意事项:

1、若要直接在客户端配置文件中配置http代理,则服务端配置文件frps.ini中必须配置vhost_http_port;

2、若在客户端配置文件中配置http代理:type = http,则必须在底部带上custom_domains=xxx.xxx.xx.xx;

2.配置代理多HTTP

上述问题1的配置方法,似乎只能代理访问一个端口的http,即使客户端配置文件frpc.ini中指定了多个type=http的 [web] 项,但因为服务端配置文件frps.ini中只能指定一个vhost_http_port=xxx,所以此方法最终还是只能代理访问一个http的服务,即vhost_http_port端口号对应的那个http。

【解决方法】:

服务端配置文件frps.ini中不需要配置vhost_http_port,直接在客户端配置文件frpc.ini中配置多个 [web] 项,即要代理的HTTP即可,其中type=tcp,也不用指定custom_domains。配置示例如下:

[common]
server_addr = 180.xx.xx.xx
server_port = 7000
token = e10adc3949ba59abbe56e057f20f883e
# 去掉速度限制
tcp_mux = false

[jira]
type = tcp
local_ip = 192.168.1.211
local_port = 8088
remote_port = 8088

[gitlab]
type = tcp
local_ip = 192.168.1.211
local_port = 8081
remote_port = 8081

小结

以上就是利用frp实现内网穿透的全过程,相比于之前介绍过的zerotier,frp无需在各个访问端上安装客户端,只需在公网服务器上安装服务端,在需要被代理转发的内网服务器上安装客户端,并配置好各个服务的端口号,其他所有用户即可在手机、PC、平板上随时随地访问内网服务。

另外,网络安全同样需要关注。由于内网穿透服务带有一定风险,因此无论是公网服务器还是内网服务器,最好都开启防火墙,用到哪个端口再放开哪个端口,服务器的密码最好也设置得复杂一些。

本文转载于网络 如有侵权请联系删除

相关文章

  • 一条SQL的执行来看看Mysql架构

    当我们在项目中使用mybatis框架执行一条mysql语句时,会经历如下过程: mysql客户端(项目)连接mysql服务端,主要作用是验证客户端的用户密码、权限等、这一步一般发生在项目启动初始化时,连接器验证通过后将连接对象保存到内存中,以便使用。mysql客户端与服务端连接后,会判断这条语句是否命中查询缓存,命中直接返回查询结果,否则进去分析器。分析器的主要功能是检查语法是否正确。符合语法规则的sql送到优化器,就是进行调优,生成一些优化方案。将调优后的sql方案传给执行器,执行器调用相应的存储引擎接口,如果是查询语句直接进行执行步骤,比如这条Sql有两个条件,会分解为两步判断。如果是更新语句则先查询出该条记录,修改后调用引擎接口,引擎会把数据保存到内存中,然后记录redolog(Innodb事务日志prepare状态),然后通知执行器可以提交了,执行器收到后记录binlog(二进制,主从复制),调用引擎接口,将redolog状态修改为提交。总结:1.mysql主要分为Server层和引擎层,Server层主要包括连接器、查询缓存、分析器、优化器、执行器同时还有一个binlog日志

  • 五、代理模式详解

    7.代理模式7.1.课程目标1、掌握代理模式的应用场景和实现原理。2、了解静态代理和动态代理的区别。3、了解CGLib和JDKProxy的根本区别。4、手写实现定义的动态代理。7.2.内容定位都知道SpringAOP是用代理模式实现,到底是怎么实现的?我们来一探究竟,并且自己仿真手写 还原部分细节。7.3.代理模式定义代理模式(ProxyPattern)是指为其他对象提供一种代理,以控制对这个对象的访问,属于结构型模式。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标 对象之间起到中介的作用。官方原文:Provideasurrogateorplaceholderforanotherobjecttocontrolaccesstoit. 首先来看代理模式的通用UML类图:代理模式一般包含三种角色:抽象主题角色(Subject):抽象主题类的主要职责是声明真实主题与代理的共同接口方法,该类可以是接口也可以是抽象类;真实主题角色(RealSubject):该类也被称为被代理类,该类定义了代理所表示的真实对象,是负责执行系统真正的逻辑业务对象;代理主题角色(P

  • 事件机制

    浏览器事件机制DOM事件模型分为捕获和冒泡。一个事件发生后,会在子元素和父元素之间传播(propagation)。事件传播分为三个阶段:捕获(Capture):事件对象从window对象传递到目标对象的过程。目标(target):目标节点在处理事件的过程。冒泡(Bubble):事件对象从目标对象传递到window对象的过程。在任一阶段调用stopPropagation都将终止本次事件的传播。注册事件注册事件使用addEventListener(event,function,useCapture),第三个参数可以是布尔值,也可以是对象。是布尔值useCapture参数的情况下,默认值为false,表示注册事件是冒泡事件,为true时表示注册事件是捕获事件。当是对象参数时,可以使用以下几个属性:capture:布尔值,同useCaptureonce:布尔值,值为true表示事件只会调用一次,调用以后移除监听passive:布尔值,表示永远不会调用prevrntDedault需要注意的是:event.target是指向引起触发事件的元素,event.currentTarget则是事件绑定的元

  • SAP SD-销售订单页签信息介绍

    介绍一些常用的销售订单页签信息。 “条件”页签: PR01,合同的定价;ZDI1,合同价格未确定时的价格;ZML1,产品目录价;VPRS,成本价; 当合同价格未确定时,PR01的值和ZDI1的值相同,需要将PR01的值复制到ZDI1中; 如果上述页面中“PR01”类型,且行项目不属于免费项目,则物料没有维护价格信息,需手工增加“PR01”类型,并维护值。 “科目分配”页签:当启用项目管理PS模块时,需选择对应的WBS元素; “计划行”页签:当分批多次交货时,可以将计划行拆分为多行,分别填写预计交货日期和数量信息; “文本”页签:可以用来填写一些备注信息,供后端获取; “销售”页签:客户组:从客户隶属关系角度对订单的分类,默认来源于售达方的客户属性; 销售地区:从地理区域角度对订单的分类,默认来源于售达方的客户属性 “装运”页签:装运类型:货物发运的运输方式; 特殊处理标:运费的承担方,“供方”或“需方” “出具发票凭证”页签:出具发票冻结:若选择提前开票冻结,表示该订单已经整单提前开票;“会计”页签:账户组:与会计账务处理科目有关,默认来源于售达方的客户属性; “合作伙伴”页签:维护联

  • 网页图片的压缩优化

    在网页建设过程中,图片的使用时必不可少的,甚至有些网站的80%~90%的部分都是图片,那么如此之多的图片怎么才能保证良好的用户体验,好的加载速度呢,其实从很多角度都可以做到提高加载速度,或者说好的用户体验,比如说lazyload思想等,下边我们从源头看看有没有方法。下面介绍外部工具实现图片优化之前介绍过一种webp格式,有在线生成工具,这种格式是未来的发展趋势,但是目前的支持度不是太好,下边来看优化jpg图片工具imageoptim。下边是在截屏之后的图片做的对比:复制其中,在imageoptim的广告词是:ImageOptimmakesimagesloadfaster,有人担心在图片优化的时候,会不会是图像的质量下降,Basically,ImageOptimworkslikemagic,cuttingdownthesizeofimageswithoutmakingthemlookworse”—MacStories 再看其原理,在保证质量的同时,删除了隐形垃圾,无缝结合了很多好的图像优化工具,最终实现了图像的优化,所以说这种担心是多余的,知道了这种方法,在以后的使用中多多的尝试哟

  • Java 回顾 ( Revisiting Java )

    最近在看一些工程代码,于是看了看设计模式,看设计模式之前发现Java是先修知识,又重新补了一遍Java,温故知新,获得一些新的体会。 本文不打算作为“Java知识点详细梳理”,“10分钟学会Java”之类的文章,仅作为博主自己的一个回顾,涉及的内容也无定法。Java应该是目前用的最多的编程语言,以前觉得Java老要点点点(调用方法),变量名也很长,C++/Python很少代码写完的东西Java可能要写很多行…… 觉得挺麻烦的,不过Java风靡自有其风靡的理由,在面向对象语言中她是一个标杆,虽然繁琐,但比较清晰,比较简单。拿变量类型来说,Java只有两种变量类型,primitive主数据类型和引用数据类型。Java中最关键的概念是面向对象,面向对象最关键的东西就是类和对象,所有的Java程序都定义在类中,你不能像python那样,打开.py文件就开始写东西,就可以执行了,也不像C++,定义一个main函数即可运行。在Java中即使main函数也要包括在类中。为什么面向对象是核心内容?它的好处在哪呢?可以说,OO(面向对象)无处不在,OO使得我们很方便的扩展功能,而不需要重复写很多代码!另

  • Effective.Java 读书笔记(12)关于Comparable接口

    12.ConsiderimplementingComparable大意为考虑实现Comparable接口 对于Comparable接口来说,其主要方法应该是compareTo方法,可是这个方法并没有在Object里面声明,而是Comparable接口中唯一的方法,这个方法所能够产生的作用并不局限于简单的比较,还可以是有顺序的比较换句话说,实现Comparable接口的类,都具有一种内在的排序关系(naturalordering),而且对该类的数组进行排序也是比较简单的,例如:Arrays.sort(a);复制对于储存在集合里面的实现了Comparable接口的对象进行搜索,计算极值之类的操作都十分简单,下面举个例子,实现了从命令行读取参数,并且自动排序并打印publicclassComparableTest{ publicstaticvoidmain(String[]args){ Set<String>s=newTreeSet<String>(); Collections.addAll(s,args); System.out.println(s); } }复制我

  • Atom

    viahttps://www.iplaysoft.com/item/atom-shortcuts文件切换ctrl-shift-s保存所有打开的文件 cmd-shift-o打开目录 cmd-\显示或隐藏目录树 ctrl-0焦点移到目录树 目录树下,使用a,m,delete来增加,修改和删除 cmd-t或cmd-p查找文件 cmd-b在打开的文件之间切换 cmd-shift-b只搜索从上次gitcommit后修改或者新增的文件导航(等价于上下左右) ctrl-p前一行 ctrl-n后一行 ctrl-f前一个字符 ctrl-b后一个字符alt-B,alt-left移动到单词开始 alt-F,alt-right移动到单词末尾cmd-right,ctrl-E移动到一行结束 cmd-left,ctrl-A移动到一行开始cmd-up移动到文件开始 cmd-down移动到文件结束ctrl-g移动到指定行row:column处cmd-r在方法之间跳转书签cmd-F2在本行增加书签 F2跳到当前文件的下一条书签 shift-F2跳到当前文件的上一条书签 ctrl-F2列出当前工程所有书签选取大部分和导航一

  • 给网站数据分析师的五个建议

    通常网站管理者都想通过网站分析来得到一定的效果,但不知道怎么做才好。实际上能否灵活的使用网站分析很大程度上取决于你如何利用网站分析。这里给大家介绍一下网站分析师应该注意的五点内容。在使用网站分析工具的公司中,有的公司能够熟练的使用网站分析工具反复优化自己的网站,随之业绩也有所增长,而有的公司虽然使用了网站分析工具但是效果不是很明显。究竟为什么会存在这样的差异呢?通过分析我发现是否能够熟练的使用网站分析取决于你是否能够巧妙的使用一些技巧。网站分析有很多技巧,下面为大家介绍其中5点: 1.始终不能忘记数据分析的目的2.充分理解网站分析可以做到的事情和做不到的事情3.分成几个部分进行数据分析4.只注重数据分析本身是不会有效果的5.不能分析所有的数据始终不能忘记数据分析的目的网站分析为我们提供了很多有关网站的数据,通过分析这些数据我们可以了解很多事情。例如:客人是通过哪些网站和广告来到网站的,在网站内的平均停留多长时间,浏览某一网页的客人的转化率是多少,等等。如果你使用是高性能网站分析工具的话,那么你还能看到更多你想要统计的数据。使用优秀的网站分析工具的话,喜欢分析的人就能够更加全面的把握网站

  • Web性能探索之旅-1.无线网络基础

    一、无所不在的连接针对不通的使用场景,无线网络技术有很多种。鉴于无线网络技术如此多样,笼统地概括所有无线网络的性能优化手段是不可能的。好在大多数无线技术的原理都是相通的,衡量性能的指标和约束条件也具有普遍实用性。只要把影响无线性能的基本原理搞清楚,那其他问题自然也就迎刃而解了。二、无线网络的性能基础香农模型:C是信道容量,单位bit/s;BW是可用带快,单位是Hz;S是信号,N是噪声,单位是W。在所有这些因素中,与数据传输速度最直接相关的就是接收端和发送端之间的可用带宽和信号强度2.1带宽带宽:频率范围的大小。根据香农的模型,信道的总体比特率与分配的带宽呈正比。在其他条件等同的情况下,频率范围加倍,传输速度加倍。2.2信号强度信号强度:又叫做信噪比(SNR)。本质上,信噪比衡量的是预期信号强度与背景噪声及干扰之间的比值。背景噪声越大,携带信息的信号就必须越强。提高信噪比:增大发射功率,缩短收发两端的距离路径损耗(通路衰减):信号强度随距离降低。2.3调制用于编码信号的算法对无线性能同样有显著影响。三、测量现实中的无线性能所有利用无线电的通信都: 1.通过共享的通信媒体(无线电波)实现;

  • Java多线程神器:join使用及原理

    join()join()是线程类Thread的方法,官方的说明是:Waitsforthisthreadtodie.等待这个线程结束,也就是说当前线程等待这个线程结束后再继续执行,下面来看这个示例就明白了。示例publicstaticvoidmain(String[]args)throwsException{ System.out.println("start"); Threadt=newThread(()->{ for(inti=0;i<5;i++){ System.out.println(i); try{ Thread.sleep(500); }catch(InterruptedExceptione){ e.printStackTrace(); } } }); t.start(); t.join(); System.out.println("end"); }复制结果输出:start 0 1 2 3 4 end复制线程t开始后,接着加入t.join()方法,t线程里面程序在主线程end输出之前全部执行完了,说明t.join()阻塞

  • delphi remobjects

    概述:RemObjectsSDK是一个先进的远程框架,允许你通过网络远程地访问驻留在服务器上的对象。RemObjectsSDK允许你开发客户/服务应用程序,利用高优化性能的SmartServices或跨平台兼容性的标准WebServices,使客户端和服务器端轻松高效的通讯。高亮特征强大的远程框架 为客户端和服务器间有效通讯提供广泛的选项,跨越各种质量的网络(从本地局域网到低可靠的广域无线网络)和不同的平台。整个通讯策略的不同选择(网络服务器和客户端,消息格式,会话数据存储和其他关键性的要素),简单的选择适当的组件,允许开发者结合解决方案以最好的满足他们的需要。ServiceBuilder RemObjectsSDK的一个关键特征是它的RADServiceBuilder应用程序,它允许你在写第一行代码前可视地定义你服务器的界面。在ServiceBuilder中,你能够定义暴露你服务的接口,客户端和服务器端发送的自定义类型,以及客户端可能触发的回调事件。ServiceBuilder还允许你编写服务接口的和类型的文档,描述它们如何被使用和实现。因为整个服务定义用一个平台和语言无关的方式描述

  • Golang 实现 Redis(3): 实现内存数据库

    本文是golang实现redis系列的第三篇,主要介绍如何实现内存KV数据库。本文完整源代码在作者Github:HDT3213/godis ConcurrentHashMap KV内存数据库的核心是并发安全的哈希表,常见的设计有几种: sync.map:golang官方提供的并发哈希表,适合读多写少的场景。但是在m.dirty刚被提升后会将m.read复制到新的m.dirty中,在数据量较大的情况下复制操作会阻塞所有协程,存在较大的隐患。关于sync.map的详细讨论推荐阅读鸟窝:sync.Map揭秘 juc.ConcurrentHashMap:java的并发哈希表采用分段锁实现。在进行扩容时访问哈希表线程都将协助进行rehash操作,在rehash结束前所有的读写操作都会阻塞。因为缓存数据库中键值对数量巨大且对读写操作响应时间要求较高,使用juc的策略是不合适的。 memcachedhashtable:在后台线程进行rehash操作时,主线程会判断要访问的哈希槽是否已被rehash从而决定操作old_hashtable还是操作primary_hashtable。 me

  • 多线程避免使用SimpleDateFormat及替代方案

    先来看一个多线程下使用例子,看到运行结果会出现异常: importjava.text.DateFormat; importjava.text.SimpleDateFormat; importjava.util.Date; importjava.util.Random; importjava.util.concurrent.ExecutorService; importjava.util.concurrent.Executors; publicclassSimpleDateFormateTest{ publicstaticvoidmain(String[]args){ finalDateFormatdf=newSimpleDateFormat("yyyyMMdd,HHmmss"); ExecutorServicets=Executors.newFixedThreadPool(100); for(;;){ ts.execute(newRunnable(){ @Override publicvoidrun(){ try{ //生成随机数,格式化日期 Stringformat=df.fo

  • 关于树的随记

    一棵树的大小是它的节点的数量。 树中的一个节点的深度是它到根节点的路径上的链接数。 树的高度是它的所有节点中的最大深度。节点数为1的树的高度是零。

  • 一个抓取知乎页面图片的简单爬虫

        在知乎上看到一个问题 能利用爬虫技术做到哪些很酷很有趣很有用的事情?发现蛮好玩的,便去学了下正则表达式,以前听说正则表达式蛮有用处的,学完后觉得确实很实用的工具。问题评论下基本都是python写的爬虫,我看了下原理,感觉爬一个简单的静态网页还是挺容易的。就是获取网站html源码,然后解析需要的字段,最后拿到字段处理(下载)。想起我学java的时候有个URL类好像有这个功能,便去翻了下api文档,发现URLConnection果然可以获取html源码。   首先从核心开始写,获取网页源码 packagemothed; importjava.io.BufferedReader; importjava.io.InputStreamReader; importjava.net.URL; importjava.net.URLConnection; /** *爬取网页源代码 *@authorganhang * */ publicclassSpider{ publicstaticStringGetContent(Stringurl){ //定义一个字符串用来存储网页内容 S

  • windows store app 如何计算字符所占的宽度

    最近在做一个PDF电子文档相关的项目,我们的app是运行在Windows8/WinRT下的。由于使用的第三方库的一些技术限制,textarea竟然不支持多行文本自动换行。于是我们就需要自己实现自动换行,实现这个功能的关键点就是要知道如何去计算一个字符,一个单词在指定了字体跟字体大小的前提下占多宽。其实我们可以使用UIElement.Measure()来实现。具体的实现代码如下: privatestaticdoubleMeasureString(stringtext,doublefontSize=7.0) { vartextBlock=newTextBlock(); textBlock.Text=text; textBlock.FontSize=fontSize; textBlock.FontFamily=newWindows.UI.Xaml.Media.FontFamily("MicrosoftYaHei"); textBlock.Measure(newSize(Double.MaxValue,Double.MaxValue)); returntextBlock.ActualWidt

  • 「转」xtrabackup新版详细说明

    声明:本文由我的同事@fiona514编写,是我看过的最用心的中文说明介绍,强烈推荐大家学习使用。   PerconaXtrabackup2.4.1 编译及软件依赖 centos5,6需要升级cmake至2.8.2版本以上,解决:安装cmake版本3.4.3测试通过 centos5gccg++需要升级gcc至4.4以上上,解决:安装4.4.7测试通过 另外xtrabackcup另外Boost版本需要1.59.0版本或以上,目前centos5,6默认是1.41.0。解决:升级至1.59.0 GTID支持情况 测试5.6,5.7开启GTID下可以正常备份,还原 对MySQL5.5,MySQL5.6版本支持 5.6在开启和关闭gtid模式下都可以正常备份还原 5.5可以正常备份还原 5.6部分表导出还原测试正常 对现有版本结合新特性的建议 目前线上版本大部分在1.6.3和1.5版本。很多需求是通过第三方工具支持。结合2.4.1的新特性和release历史和目前情况,建议几点如下: *xtrabackup支持非Innodb表备份,并且Innobackupex在下一版本中移除,建议通过

  • java Integer

    Java中的数据类型分为基本数据类型和引用数据类型   int是基本数据类型,Integer是引用数据类型;   Ingeter是int的包装类,int的初值为0,Ingeter的初值为null。 初始化   inti=1;   Integeri=newInteger(1); 自动装箱和拆箱  从Java5.0版本以后加入了autoboxing功能;  

  • 记一次项目中的css样式复用

    本文同步至微信公众号:http://mp.weixin.qq.com/s?__biz=MzAxMzgwNDU3Mg==&mid=401616238&idx=1&sn=3c6e965283c632e9035875be43e6a305&scene=0#wechat_redirect 二维码: 一直觉得css是一个不被重视,或者说是重视不够的饭后甜点。因为它太“简单”,门槛低,不能彰显或提升广大闷骚程序猿的逼格。。。一直都想聊聊css相关的一些杂碎。正好借最近的一次项目实践来侃侃css。     玉伯曾发文章做过类似的比喻说:“css就像语文。大家都认识汉字,也都会写汉字,但是也只有那些牛逼的作家才能写出优秀的文章,而我们却不能”。也就是说css易学难用。一个项目随着页面的增多,css的代码数量也可能直线飙升。不仅加载起来比较慢,对维护的人来说,也不确定这些代码都有什么地方在用,轻易不敢动。。因此,css样式复用的重要性就可想而知了。而这个也是新手或对css不够重视的人欠缺的。。    &

  • Java并发编程经典50问

    首先给大家分享一个github仓库,上面放了200多本经典的计算机书籍,包括C语言、C++、Java、Python、前端、数据库、操作系统、计算机网络、数据结构和算法、机器学习、编程人生等,可以star一下,下次找书直接在上面搜索,仓库持续更新中~ github地址:https://github.com/Tyson0314/java-books 如果github访问不了,可以访问gitee仓库。 gitee地址:https://gitee.com/tysondai/java-books 线程池 线程池:一个管理线程的池子。 为什么使用线程池? 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。 提高响应速度。当任务到达时,可以不需要等到线程创建就能立即执行。 提高线程的可管理性。统一管理线程,避免系统创建大量同类线程而导致消耗完内存。 线程池执行原理? 创建新的线程需要获取全局锁,通过这种设计可以尽量避免获取全局锁,当ThreadPoolExecutor完成预热之后(当前运行的线程数大于等于corePoolSize),提交的大部分任务都会被放到Blocking

相关推荐

推荐阅读