下载编译:部署 web 程序

step0#
下载编译:

Copy
git clone https://github.com/jadepeng/simplepv
cd simplepv
mvn package -DskipTests
部署 web 程序

Copy
java -jar simplepv-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
输出

Copy
2021-12-02 20:25:49.014 INFO 35916 — [ main] com.jadepeng.simplepv.SimplepvApp : The following profiles are active: prod
2021-12-02 20:25:53.585 INFO 35916 — [ main] c.j.simplepv.config.WebConfigurer : Web application configuration, using profiles: prod
2021-12-02 20:25:53.589 INFO 35916 — [ main] c.j.simplepv.config.WebConfigurer : Web application fully configured
2021-12-02 20:26:02.580 INFO 35916 — [ main] org.jboss.threads : JBoss Threads version 3.1.0.Final
2021-12-02 20:26:02.697 INFO 35916 — [ main] com.jadepeng.simplepv.SimplepvApp : Started SimplepvApp in 15.936 seconds (JVM running for 16.79)
2021-12-02 20:26:02.707 INFO 35916 — [ main] com.jadepeng.simplepv.SimplepvApp :

Application 'simplepv' is running! Access URLs:
Local: 		http://localhost:58080/
External: 	http://172.1.1.12:58080/
Profile(s): 	[prod]

本程序默认使用 h2 作为存储,所以不用另外安装 mysql。

step1#
引用 client.js, 也可以直接放入到网页中

Copy
var bszCaller, bszTag, scriptTag, ready;

var t,
e,
n,
a = !1,
c = [];

// 修复Node同构代码的问题
if (typeof document !== ‘undefined’) {
(ready = function (t) {
return (
a || ‘interactive’ === document.readyState || ‘complete’ === document.readyState
? t.call(document)
: c.push(function () {
return t.call(this);
}),
this
);
}),
(e = function () {
for (var t = 0, e = c.length; t < e; t++) c[t].apply(document);
c = [];
}),
(n = function () {
a ||
((a = !0),
e.call(window),
document.removeEventListener
? document.removeEventListener(‘DOMContentLoaded’, n, !1)
: document.attachEvent &&
(document.detachEvent(‘onreadystatechange’, n), window == window.top && (clearInterval(t), (t = null))));
}),
document.addEventListener
? document.addEventListener(‘DOMContentLoaded’, n, !1)
: document.attachEvent &&
(document.attachEvent(‘onreadystatechange’, function () {
/loaded|complete/.test(document.readyState) && n();
}),
window == window.top &&
(t = setInterval(function () {
try {
a || document.documentElement.doScroll(‘left’);
} catch (t) {
return;
}
n();
}, 5)));
}

bszCaller = {
fetch: function (t, e) {
var n = ‘SimplePVCallback’ + Math.floor(1099511627776 * Math.random());
t = t.replace(’=SimplePVCallback’, ‘=’ + n);
(scriptTag = document.createElement(‘SCRIPT’)),
(scriptTag.type = ‘text/javascript’),
(scriptTag.defer = !0),
(scriptTag.src = t),
document.getElementsByTagName(‘HEAD’)[0].appendChild(scriptTag);
window[n] = this.evalCall(e);
},
evalCall: function (e) {
return function (t) {
ready(function () {
try {
e(t),
scriptTag && scriptTag.parentElement && scriptTag.parentElement.removeChild && scriptTag.parentElement.removeChild(scriptTag);
} catch (t) {
console.log(t), bszTag.hides();
}
});
};
},
};

const fetch = siteUrl => {
bszTag && bszTag.hides();
bszCaller.fetch(${siteUrl}/api/pv/${window.btoa(location.href)}?jsonpCallback=SimplePVCallback, function (t) {
bszTag.texts(t), bszTag.shows();
});
};

bszTag = {
bszs: [‘site_pv’, ‘page_pv’],
texts: function (n) {
this.bszs.map(function (t) {
var e = document.getElementById(‘busuanzi_value_’ + t);
e && (e.innerHTML = n[t]);
});
},
hides: function () {
this.bszs.map(function (t) {
var e = document.getElementById(‘busuanzi_container_’ + t);
e && (e.style.display = ‘none’);
});
},
shows: function () {
this.bszs.map(function (t) {
var e = document.getElementById(‘busuanzi_container_’ + t);
e && (e.style.display = ‘inline’);
});
},
};

if (typeof document !== ‘undefined’) {
fetch(‘http://localhost:8080/’);
}
上面 fetch 的地址,填写 webserver 部署后的地址。

step2#
在需要显示 pv 的地方

Copy
本站总访问量
本文总阅读量
原理#
当前只统计了PV,未统计uv,后续有空可以增加。

原理,每个url存储一条记录

Copy
public class PV implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;

@Column(name = "url")
private String url;

@Column(name = "pv")
private Integer pv;

}
统计PV时,lock url的host,获取pv对象,如果不存在则新增,然后pv+1

注意: 这里用了个lock,防止并发出错

Copy
@Override
public PVDTO increment(String url) {
Lock lock = null;
// 简单锁一下
try {
URL uri = new URL(url);
lock = this.lock(uri.getHost(), 30000);
if (lock == null) {
throw new RuntimeException(“请稍后重试”);
}

        PV pv = incrementPV(url);

        PV sitePv = incrementPV(uri.getHost());

        return new PVDTO(pv.getPv(), sitePv.getPv());
    } catch (MalformedURLException e) {
        throw new RuntimeException("url not support");
    } finally {
        if (lock != null) {
            this.releaseLock(lock);
        }
    }
}

private PV incrementPV(String url) {
    PV pv = this.pVRepository.findFirstByUrl(url).orElse(new PV().url(url).pv(0));
    pv.setPv(pv.getPv() + 1);
    this.pVRepository.save(pv);
    return pv;
}
亚马逊测评 www.yisuping.cn
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值