这篇文章主要介绍了linux中shell脚本编写和运行的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。编写第一个shell脚本在gedit中编写.sh格式的文件,保存为a.sh。 代码:#! /bin/bash # employ bash shellplayer1=xiaoming # define a player1player2=ken echo "Game start! $player1 $player2" # echo is used to printf in terminal在终端调用脚本,定位到目录,然后输入:bash a.sh看到打印结果如上所示。编写第一个if/else脚本编写的if/else如下: if和 ; 之间的代码ls -l a.sh是用来判断当前的目录下是否存在a.sh这个文件。if和else的基本格式如下所示,if command ; then code1 else code2 fi在终端调用的结果如下,可以看到输出了ls return true再看一个if/else脚本如下脚本,if/else格式和上面格式一致,重点看下 if 和 ;间的那个命令,命令开始以 [,后面有4个参数 $1,=,me,]输出的结果如下所示:用 = 来判断输入的字符串是否等于me。其他的常用判断参数见下图:看一个for循环for循环的格式如下脚本所示:#! /bin/bash # employ bash shellfor num in 1 2 3 4 5 sixdo echo "num=$num"for(( num=1; num<7; num++)) # method2do echo "num=$num"donewhile循环while循环的基本格式如下:#! /bin/bashi=7 j=10while [ $i -lt $j ] do echo "num1 = $i, num2=$j" ((i++))done感谢你能够认真阅读完这篇文章,希望小编分享的“linux中shell脚本编写和运行的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持辰讯云,关注辰讯云资讯频道,更多相关知识等着你来学习!...
这篇文章主要为大家展示了“磁盘慢会导致Linux负载飙升的原因”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“磁盘慢会导致Linux负载飙升的原因”这篇文章吧。 一、CPU利用率和负载率的区别这里要区别CPU负载和CPU利用率,它们是不同的两个概念,但它们的信息可以在同一个top命令中进行显示。CPU利用率显示的是程序在运行期间实时占用的CPU百分比,这是对一个时间段内CPU使用状况的统计,通过这个指标可以看出在某一个时间段内CPU被占用的情况, 如果被占用时间很高,那么就需要考虑CPU是否已经处于超负荷运作。而CPU负载显示的是在一段时间内CPU正在处理以及等待CPU处理的进程数之和的统计信息,也就是CPU使用队列的长度的统计信息。CPU利用率高并不意味着负载就一定大,可能这个任务是一个CPU密集型的。一样CPU低利用率的情况下是否会有高Load Average的情况产生呢?理解占有时间和使用时间就可以知道,当CPU分配时间片以后,是否使用完全取决于使用者,因此完全可能出现低利用率高Load Average的情况。另外IO设备也可能导致CPU负载高。由此来看,仅仅从CPU的使用率来判断CPU是否处于一种超负荷的工作状态还是不够的,必须结合Load Average来全局的看CPU的使用情况。网上有个例子来说明两者的区别如下:某公用电话亭,有一个人在打电话,四个人在等待,每人限定使用电话一分钟,若有人一分钟之内没有打完电话,只能挂掉电话去排队,等待下一轮。电话在这里就相当于CPU,而正在或等待打电话的人就相当于任务数。在电话亭使用过程中,肯定会有人打完电话走掉,有人没有打完电话而选择重新排队,更会有新增的人在这儿排队,这个人数的变化就相当于任务数的增减。为了统计平均负载情况,我们5秒钟统计一次人数,并在第1、5、15分钟的时候对统计情况取平均值,从而形成第1、5、15分钟的平均负载。有的人拿起电话就打,一直打完1分钟,而有的人可能前三十秒在找电话号码,或者在犹豫要不要打,后三十秒才真正在打电话。如果把电话看作CPU,人数看作任务,我们就说前一个人(任务)的CPU利用率高,后一个人(任务)的CPU利用率低。当然, CPU并不会在前三十秒工作,后三十秒歇着,CPU是一直在工作。只是说,有的程序涉及到大量的计算,所以CPU利用率就高,而有的程序牵涉到计算的部分很少,CPU利用率自然就低。但无论CPU的利用率是高是低,跟后面有多少任务在排队没有必然关系。CPU数量和CPU核心数(即内核数)都会影响到CPU负载,因为任务最终是要分配到CPU核心去处理的。两块CPU要比一块CPU好,双核要比单核好。因此,我们需要记住,除去CPU性能上的差异,CPU负载是基于内核数来计算的,即“有多少内核,即有多少负载”,如单核最好不要超过100%,也就是负载为1.00,如此类推。Linux里有一个/proc目录,存放的是当前运行系统的虚拟映射,其中有一个文件为cpuinfo,这个文件里存放着CPU的信息。/proc/cpuinfo文件按逻辑CPU而非真实CPU分段落显示信息,每个逻辑CPU的信息占用一个段落,第一个逻辑CPU标识从0开始。$ cat /proc/cpuinfo processor : 0vendor_id : GenuineIntelcpu family : 6model : 63model name : Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHzstepping : 2microcode : 0x36cpu MHz : 2399.998cache size : 20480 KBphysical id : 0siblings : 2core id : 0cpu cores : 2apicid : 0initial apicid : 0fpu : yesfpu_exception : yescpuid level : 15wp : yesflags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr ......bogomips : 4799.99clflush size : 64cache_alignment : 64address sizes : 42 bits physical, 48 bits virtualpower management:要理解该文件中的CPU信息,有几个相关的概念要知道,如:processor表示逻辑CPU的标识、model name表示真实CPU的型号信息、physical id表示真实CPU和标识、cpu cores表示真实CPU的内核数等等。逻辑CPU的描述:现在的服务器一般都使用了“超线程”(Hyper-Threading,简称HT)技术来提高CPU的性能。超线程技术是在一颗CPU同时执行多个程序而共同分享一颗CPU内的资源,理论上要像两颗CPU一样在同一时间执行两个线程。虽然采用超线程技术能同时执行两个线程,但它并不象两个真正的CPU那样,每各CPU都具有独立的资源。当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲置后才能继续。因此超线程的性能并不等于两颗CPU的性能。具有超线程技术的CPU还有一些其它方面的限制。二、CPU负载率的计算方式Load average的概念源自UNIX系统,虽然各家的公式不尽相同,但都是用于衡量正在使用CPU的进行数量和正在等待CPU的进程数量,一句话就是runable processes的数量。所以Load average可以作为CPU瓶颈的参考指标,如果大于CPU的数量,说明CPU可能不够用了。但是,在Linux上有点差异!Linux上的load average除了包括正在使用CPU的进程数量和正在等待CPU的进程数量之外,还包括uninterruptible sleep的进程数量。通常等待IO设备、等待网络的时候,进程会处于uninterruptible sleep状态。Linux设计者的逻辑是,uninterruptible sleep应该都是很短暂的,很快就会恢复运行,所以被等同于runnable。然而uninterruptible sleep即使再短暂也是sleep,何况现实世界中uninterruptible sleep未必很短暂,大量的、或长时间的uninterruptible sleep通常意味着IO设备遇到了瓶颈。众所周知,sleep状态的进程是不需要CPU的,即使所有的CPU都空闲,正在sleep的进程也是运行不了的,所以sleep进程的数量绝对不适合用作衡量CPU负载的指标,Linux把uninterruptible sleep进程算进load average的做法直接颠覆了load average的本来意义。所以在Linux系统上,load average这个指标基本失去了作用,因为你不知道它代表什么意思,当看到load average很高的时候,你不知道是runnable进程太多还是uninterruptible sleep进程太多,也就无法判断是CPU不够用还是IO设备有瓶颈。从另一个方面来说,也就可以解释为什么磁盘慢时(大量磁盘使用时),CPU负载会飙高了。基本上我碰到CPU负载高的情况就两种情况:CPU本身处理太多任务,再加上软中断和上下文切换太频繁导致负载高;再就是磁盘太慢导致了不可中断睡眠太多导致CPU负载高。以上是“磁盘慢会导致Linux负载飙升的原因”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注辰讯云资讯频道!...
这篇文章主要为大家展示了“微信小程序中如何实现圆形菜单”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“微信小程序中如何实现圆形菜单”这篇文章吧。建行APP首页有个圆形菜单.仿了个玩具出来.功能介绍: 1.一个圆形背景.六个item菜单.中间是微信用户的头像; 2.触摸滚动.速度较小时,随手指滚动,手指抬起,滚动停止;速度较大时,随手指滚动,手指抬起,还会自动滚动一段时间; 上一张真机截图: 上代码: 1.index.jsvar app = getApp() Page({ data: { userInfo: {}, menuList: {},//菜单集合 animationData: {}, startPoint: {},//触摸开始 dotPoint: {},//圆点坐标 startAngle: 0,//开始角度 tempAngle: 0,//移动角度 downTime: 0,//按下时间 upTime: 0,//抬起时间 // isRunning: false,//正在滚动 }, onLoad: function () { var that = this //调用应用实例的方法获取全局数据 app.getUserInfo(function (userInfo) { //更新数据 that.setData({ userInfo: userInfo, }) }) wx.getSystemInfo({ success: function (res) { var windowWidth = res.windowWidth * 0.5; that.setData({ //圆点坐标,x为屏幕一半,y为半径与margin-top之和,px //后面获取的触摸坐标是px,所以这里直接用px. dotPoint: { clientX: windowWidth, clientY: 250 } }) } }) }, onReady: function (e) { var that = this; app.menuConfig = { menu: [ { 'index': 0, 'menu': '我的账户', 'src': '../images/account.png' }, { 'index': 1, 'menu': '信用卡', 'src': '../images/card.png' }, { 'index': 2, 'menu': '投资理财', 'src': '../images/investment.png' }, { 'index': 3, 'menu': '现金贷款', 'src': '../images/loan.png' }, { 'index': 4, 'menu': '特色服务', 'src': '../images/service.png' }, { 'index': 5, 'menu': '转账汇款', 'src': '../images/transfer.png' } ] } // 绘制转盘 var menuConfig = app.menuConfig.menu, len = menuConfig.length, menuList = [], degNum = 360 / len // 文字旋转 turn 值 for (var i = 0; i < len; i++) { menuList.push({ deg: i * degNum, menu: menuConfig[i].menu, src: menuConfig[i].src }); console.log("menu:" + menuConfig[i].menu) } that.setData({ menuList: menuList }); }, // 菜单拖动的三个方法 buttonStart: function (e) { this.setData({ startPoint: e.touches[0] }) var x = this.data.startPoint.clientX - this.data.dotPoint.clientX; var y = this.data.startPoint.clientY - this.data.dotPoint.clientY; var startAngle = Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI; this.setData({ startAngle: startAngle }) }, buttonMove: function (e) { //获取滑动时的时间 var downTime = Date.now(); this.setData({ downTime: downTime }) var that = this; var endPoint = e.touches[e.touches.length - 1] //根据触摸位置计算角度 var x = endPoint.clientX - this.data.dotPoint.clientX; var y = endPoint.clientY - this.data.dotPoint.clientY; var moveAngle = Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI var quadrant = 1; if (x >= 0) { quadrant = y >= 0 ? 4 : 1; } else { quadrant = y >= 0 ? 3 : 2; } var tempAngle = 0; // 如果是一、四象限,则直接end角度-start角度,角度值都是正值 if (quadrant == 1 || quadrant == 4) { tempAngle += moveAngle - this.data.startAngle; } else // 二、三象限,色角度值是负值 { tempAngle += this.data.startAngle - moveAngle; } var menuConfig = app.menuConfig.menu; var menuList = []; for (var i = 0; i < this.data.menuList.length; i++) { menuList.push({ deg: this.data.menuList[i].deg + tempAngle, menu: menuConfig[i].menu, src: menuConfig[i].src }); } this.setData({ menuList: menuList }) //重置开始角度 this.setData({ startPoint: e.touches[e.touches.length - 1] }) var endX = this.data.startPoint.clientX - this.data.dotPoint.clientX; var endY = this.data.startPoint.clientY - this.data.dotPoint.clientY; var startAngle = Math.asin(endY / Math.hypot(endX, endY)) * 180 / Math.PI; this.setData({ startAngle: startAngle, tempAngle: tempAngle }) }, buttonEnd: function (e) { // 计算,每秒移动的角度 var that = this; var upTime = Date.now(); var angleSpeed = this.data.tempAngle * 1000 / (upTime - this.data.downTime); if (Math.abs(angleSpeed) < 100) { //速度小于100时,停止滚动 return } else { //速度大于100时,自动滚动 if (angleSpeed > 0) { if (angleSpeed > 500) angleSpeed = 500 var animationRun = wx.createAnimation({ duration: 2000, //ease-out结束时减速 timingFunction: 'ease-out' }) that.animationRun = animationRun animationRun.rotate(angleSpeed).step() that.setData({ animationData: animationRun.export(), }) } else { if (angleSpeed < -500) angleSpeed = -500 angleSpeed = Math.abs(angleSpeed); var animationRun = wx.createAnimation({ duration: 2000, // ease-out结束时减速 timingFunction: 'ease-out' }) that.animationRun = animationRun animationRun.rotate(-angleSpeed).step() that.setData({ animationData: animationRun.export(), }) } } } })2.index.wxml<view class="circle-out"> <view class="circle-in"> <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}"></image> <view class="menu-list" catchtouchmove="buttonMove" catchtouchstart="buttonStart" catchtouchend="buttonEnd"> <view class="menu-item" wx:for="{{menuList}}" wx:key="unique" animation="{{animationData}}"> <view class="menu-circle-item" style="-webkit-transform: rotate({{item.deg}}deg);" data-menu="{{item.menu}}"> <image class="image-style" src="{{item.src}}"></image> </view> <view class="menu-circle-text-item" style="-webkit-transform: rotate({{item.deg}}deg);"> <text class="text-style">{{item.menu}}</text> </view> </view> </view> </view></view>3.index.wxsspage { background-image: url('http://ac-ejx0nsfy.clouddn.com/ac767407f474e1c3970a.jpg'); background-attachment: fixed; background-repeat: no-repeat; background-size: cover; }.circle-out { margin: 75px auto; position: relative; width: 350px; height: 350px; border-radius: 50%; background-color: #415cab; }.userinfo-avatar { width: 70px; height: 70px; border-radius: 50%; position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; }/**子控件的透明度等于父控件透明度*子控件透明度,父控件的opacity设置后, 所以子控件opacity设置为1依然无效,必须分离开 */.circle-in { position: absolute; width: 330px; height: 330px; border-radius: 50%; top: 0; bottom: 0; left: 0; right: 0; margin: auto; background-color: #fff; }/**菜单*/.menu-list { position: absolute; left: 0; top: 0; width: inherit; height: inherit; }.menu-item { position: absolute; left: 0; top: 0; width: 100%; height: 100%; font-weight: 500; }.menu-circle-item { -webkit-transform-origin: 50% 150px; transform-origin: 50% 150px; margin: 0 auto; margin-top: 15px; position: relative; height: 50px; width: 50px; background-color: #77c2fc; text-align: center; border-radius: 50%; }.image-style { height: 25px; width: 25px; color: #f00; margin: 12.5px auto; }.text-style { margin: 5px auto; font-size: 15px; }/***/.menu-circle-text-item { -webkit-transform-origin: 50% 100px; transform-origin: 50% 100px; margin: 0 auto; position: relative; height: 25px; width: auto; text-align: center; }js注释补充: 获取手指抬起时的角速度 1.获取角度.借图说话. Math.sqrt( x * x + y * y )是斜边长,乘以 sin a 就是 y 的长度; 获取a的角度:Math.asin(y / Math.hypot(x, y) ; [ hypot是x * x + y * y ] 2.根据角度差计算角速度 var angleSpeed = this.data.tempAngle * 1000 / (upTime - this.data.downTime);3.当角速度小于100的时候触摸滑动停止,不自动滚动;大于100时,自动滚动.我这里用动画,有个问题:很难把握动画持续时间和速度的关系.总感觉不够流畅.我表示不能忍. 4.分象限的问题.看看代码就知道了.主要是根据up时的触摸点相对于圆点的X轴差值来计算.大于0就是一四象限.小于0就是二三象限.以上是“微信小程序中如何实现圆形菜单”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注辰讯云资讯频道!...
这篇文章主要介绍php中正则表达式的定界符是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!正则表达式的定界符:正则表达式就是用来声明正则表达式边界的符号,正则表达式是字符串类型。所以在定义正则表达式时先定义字符串类型;正则表达式常用的边界符"/ ,实际上字母和非数字字符以及“V之外的字符都可以做正则表达式的边界符使用。注意:一个完整的正则表达式准确的说有两个边界符。第一个是字符串类型的引号边界符第二个是正则表达式的边界符例如:$parrten = '';具体我们以代码演示为例:<?php/******正则表达式的定界符*****/$pattern = '/ /'; $str = '';//进行匹配preg_match( $pattern, $str);?>代码解析:首先我们先定义一个变量$pattern,对于我们在代码中写的字符串如果不和函数一起使用,那他就是一个普通的字符串,因此我们需要进行匹配,我们所需要的匹配函数是(preg_match),定义完之后,我们还需要给定两个参数,我们需要和str进行匹配,然后我们进行运行,如果preg_match进行报错,那么就说明我们刚刚定义的不能当定界符;我们运行结果发现,没有任何报错(运行结果如下),也就是说,我们刚刚定义的是可以当做正则表达式的定界符的;运行结果:在比如说,我们把刚刚定义的$pattern = '/ /'转换为返斜线\\,是不是还会运行成功,我们在运行结果会发现,会报错,也就是说,我们用反斜线不能当正则表达式的定界符;因为它本身就是有意义的,他是我们常说的转义字符,(分隔符不能是字母数字或反斜杠)<?php /******正则表达式的定界符*****/ //$pattern = '/ /';$pattern = '\ \';$str = ''; //进行匹配 preg_match( $pattern, $str); ?>运行结果:以上是“php中正则表达式的定界符是什么”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注辰讯云资讯频道!...
这篇文章将为大家详细讲解有关微信小程序中底部导航栏目的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。微信小程序 底部导航栏目开发我们先来看个效果图这里,我们添加了三个导航图标,因为我们有三个页面,微信小程序最多能加5个。那他们是怎么出现怎么着色的呢?两步就搞定!1. 图标准备阿里图标库 http://www.iconfont.cn/collections/show/29我们进入该网站,鼠标滑到一个喜欢的图标上面 点击下方的 下载按钮在弹出框中 选择了 俩个不同颜色的 图标 选择64px大小即可,我选择的是png 然后下载下来 起上别名将上述起好名字的图标 保存到 小程序 项目目录中 新创建的 images 文件夹中,准备工作就做好了2. 更改配置文件我们找到项目根目录中的配置文件 app.json 加入如下配置信息"tabBar": { "color": "#a9b7b7", "selectedColor": "#11cd6e", "borderStyle":"white", "list": [{ "selectedIconPath": "images/111.png", "iconPath": "images/11.png", "pagePath": "pages/index/index", "text": "首页" }, { "selectedIconPath": "images/221.png", "iconPath": "images/22.png", "pagePath": "pages/logs/logs", "text": "日志" }, { "selectedIconPath": "images/331.png", "iconPath": "images/33.png", "pagePath": "pages/test/test", "text": "开心测试" }] },解释一下 对应的属性信息tabBar 指底部的 导航配置属性color 未选择时 底部导航文字的颜色selectedColor 选择时 底部导航文字的颜色borderStyle 底部导航边框的样色(注意 这里如果没有写入样式 会导致 导航框上边框会出现默认的浅灰色线条)list 导航配置数组selectedIconPath 选中时 图标路径iconPath 未选择时 图标路径pagePath 页面访问地址text 导航图标下方文字关于“微信小程序中底部导航栏目的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。...
小编给大家分享一下IIS中实现备份和还原的方法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!备份 IIS 配置若要备份 IIS 配置,请按照下列步骤操作: 1. 在本地计算机上的 IIS 管理单元中,单击 Internet 信息服务下面的计算机图标。 2. 单击操作并选择备份/还原配置。 3. 单击创建备份,选择备份文件的名称,然后单击确定。备注:默认备份位置是 %SystemRoot%\system32\inetsrv\MetaBack 文件夹。如果要将备份文件保存到其他位置,可以将文件从该默认位置复制到另一个位置。在默认位置保存一个副本以便方便地恢复。请注意,在默认情况下,C:\Winnt 是 Microsoft Windows 2000 中的 %SystemRoot% 文件夹。 4. 单击关闭。备注: 此备份方法提供只还原 IIS 设置(而不是内容文件)的方法。如果重新安装操作系统,则此备份方法无效。无法使用备份文件在正运行 Windows 2000 的其他计算机上还原 IIS 配置。 back to the top 还原 IIS 配置根据您是否删除和重新安装了 IIS,还原配置的步骤也将有所不同。备注:如果您要还原 IIS 配置并且只有元数据库文件的较旧的副本存在或者不存在元数据库文件的任何副本,请参见下面的 Microsoft 知识库文章: 234429 How to Manually Restore the Metabase When No Backup Exists(在没有任何备份存在时如何手动还原元数据库) 不进行 IIS 重新安装就还原 IIS 配置若要在尚未删除和重新安装 IIS 的情况下还原 IIS 配置,请按照下列步骤操作: 1. 在本地计算机上的 IIS 管理单元中,单击 Internet 信息服务下面的计算机图标。 2. 单击操作并选择备份/还原配置。 3. 在配置备份名对话框中,选择一个备份文件并单击还原。在系统询问您是否要还原配置设置时,单击是。 back to the top 在 IIS 重新安装后还原 IIS 配置若要在已删除和重新安装 IIS 后还原 IIS 配置,请按照下列步骤操作:1. 在本地计算机上的 IIS 管理单元中,单击 Internet 信息服务下面的计算机图标。 2. 单击操作并选择备份/还原配置。 3. 在配置备份名对话框中,选择已创建的备份文件,然后单击还原。尽管错误消息指示还原已失败,仍还原了一部分的备份配置。 4. 在命令提示符下,键入以下命令: cscript.exeX:\InetPub\AdminScripts\Adsutil.vbs enum w3svc其中,X 是安装 IIS 的驱动器的驱动器号。从列出的设置中,找到 WamUserName 和关联的 WAMUserPass 值。备注: 若要使用 Adsutil.vbs 实用程序,必须安装 Windows Script Host。 5. 单击开始,指向设置,单击控制面板,双击管理工具,然后双击计算机管理。单击本地用户管理器并单击用户。 6. 双击 IWAM_computername 用户帐户。键入您从前一步骤检索的 WAMUserPass 值,然后单击确定。 7. 在配置备份名对话框中,选择已创建的备份文件,然后单击还原。这可以完全还原您的配置。备注: 如果您更改进程外应用程序的标识,则这些应用程序回复为以前的 IWAM 用户名。 以上是“IIS中实现备份和还原的方法”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注辰讯云资讯频道!...
免备案云服务器是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。现在不用备案的云服务器,有中国港澳台、美国及海外其他国家地区的主机。不过,国内服务器(除港澳台外)都是需要经过备案,才能解析域名,用于搭建网站使用。使用免备案云服务器,无需经历备案的过程,节省时间,利于企业快速上线。免备案云服务器,比较适合外贸网站用户。国内网站在海外访问时,会有局限性。而海外云主机访问没有限制,且避免了南北互通问题,也就是所谓电信、联通等的差异。用户可以自由访问,无需担心不同网络间访问受限。美国云服务器美国云服务中心拥有高级的安保措施,数据安全性和服务稳定性是世界一流标准。ip资源丰富,技术发展成熟,且价格也相对便宜。在全球的访问速度都比较快,即买即用,高速连接,低延迟,集群化管理,分布式存储设计,深受全球站长信赖。香港云服务器美国云服务器虽然好,但香港地区具有地域优势,速度快,对于国内大陆用户来说,线路铺设距离短,故障率低,排障工作也容易进行。同时它也采用了国际带宽,更主要的是也可以享受海外云服务器同等待遇,无需备案,即开即用。香港与世界其他国家的互联网是畅通的,没有防火墙的限制,同时香港拥有互联网在亚洲的几大专线接口之一。所以访问的速度是很快的,这也是很多外贸公司以及客户主要是国外的网站选择香港云服务器的原因。对于国内人士来讲,香港云服务器更加符合使用习惯,速度快,可免除语音障碍。沟通交流起来也比较方便,有什么不清楚的直接联系即可。看完上述内容,你们掌握免备案云服务器是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注辰讯云资讯频道,感谢各位的阅读!...
这篇文章主要介绍了微信小程序中用户数据解密的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。微信小程序 用户数据解密官方指引图:引导图一步一步操作1、获取codeonLoad: function (options) { // 页面初始化 options为页面跳转所带来的参数 let that = this wx.login({ success: function (res) { // success let code = res.code that.setData({ code: code }) wx.getUserInfo({ success: function (res) { // success that.setData({ userInfo: res.userInfo }) that.setData({ iv: res.iv }) that.setData({ encryptedData: res.encryptedData }) that.get3rdSession() } }) } }) }2、发送code到第三方服务器,获取3rd_sessionget3rdSession:function(){ let that = this wx.request({ url: 'https://localhost:8443/get3rdSession', data: { code: this.data.code }, method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT // header: {}, // 设置请求的 header success: function (res) { // success var sessionId = res.data.session; that.setData({ sessionId: sessionId }) wx.setStorageSync('sessionId', sessionId) that.decodeUserInfo() } }) }3、在第三方服务器上发送appid、appsecret、code到微信服务器换取session_key和openid这里使用JFinal搭建的服务器Redis配置public void configPlugin(Plugins me) { //用于缓存userinfo模块的redis服务 RedisPlugin userInfoRedis = new RedisPlugin("userInfo","localhost"); me.add(userInfoRedis); }获取第三方sessionpublic void get3rdSession() { //获取名为userInfo的Redis Cache对象 Cache userInfoCache = Redis.use("userInfo"); String sessionId = ""; JSONObject json = new JSONObject(); String code = getPara("code"); String url = "https://api.weixin.qq.com/sns/jscode2session?appid=wx7560b8008e2c445d&secret=f1af3312b7038513fd17dd9cbc3b357c&js_code=" + code + "&grant_type=authorization_code"; //执行命令生成3rd_session String session = ExecLinuxCMDUtil.instance.exec("cat /dev/urandom |od -x | tr -d ' '| head -n 1").toString(); json.put("session", session); //创建默认的httpClient实例 CloseableHttpClient httpClient = getHttpClient(); try { //用get方法发送http请求 HttpGet get = new HttpGet(url); System.out.println("执行get请求:...." + get.getURI()); CloseableHttpResponse httpResponse = null; //发送get请求 httpResponse = httpClient.execute(get); try { //response实体 HttpEntity entity = httpResponse.getEntity(); if (null != entity) { String result = EntityUtils.toString(entity); System.out.println(result); JSONObject resultJson = JSONObject.fromObject(result); String session_key = resultJson.getString("session_key"); String openid = resultJson.getString("openid"); //session存储 userInfoCache.set(session,session_key+","+openid); } } finally { httpResponse.close(); } } catch (Exception e) { e.printStackTrace(); } finally { try { closeHttpClient(httpClient); } catch (IOException e) { e.printStackTrace(); } } renderJson(json); }private CloseableHttpClient getHttpClient() { return HttpClients.createDefault(); }private void closeHttpClient(CloseableHttpClient client) throws IOException { if (client != null) { client.close(); } }ExecLinuxCMDUtil.Javaimport java.io.InputStreamReader;import java.io.LineNumberReader;/** * java在linux环境下执行linux命令,然后返回命令返回值。 * Created by LJaer on 16/12/22. */public class ExecLinuxCMDUtil { public static final ExecLinuxCMDUtil instance = new ExecLinuxCMDUtil(); public static Object exec(String cmd) { try { String[] cmdA = { "/bin/sh", "-c", cmd }; Process process = Runtime.getRuntime().exec(cmdA); LineNumberReader br = new LineNumberReader(new InputStreamReader( process.getInputStream())); StringBuffer sb = new StringBuffer(); String line; while ((line = br.readLine()) != null) { System.out.println(line); sb.append(line).append("\n"); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); } return null; } }4、解密用户数据decodeUserInfo:function(){ let that = this wx.request({ url: 'https://localhost:8443/decodeUserInfo', data: { encryptedData: that.data.encryptedData, iv: that.data.iv, session: wx.getStorageSync('sessionId') }, method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT // header: {}, // 设置请求的 header success: function (res) { // success console.log(res) } }) }console输出结果:后端解密代码/** * 解密用户敏感数据 */public void decodeUserInfo(){ String encryptedData = getPara("encryptedData"); String iv = getPara("iv"); String session = getPara("session"); //从缓存中获取session_key //获取名称为userInfo的Redis Cache对象 Cache userInfoRedis = Redis.use("userInfo"); Object wxSessionObj = userInfoRedis.get(session); if(null==wxSessionObj){ renderNull(); } String wxSessionStr = (String)wxSessionObj; String session_key = wxSessionStr.split(",")[0]; try { byte[] resultByte = AESUtil.instance.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(session_key), Base64.decodeBase64(iv)); if(null != resultByte && resultByte.length > 0){ String userInfo = new String(resultByte, "UTF-8"); System.out.println(userInfo); JSONObject json = JSONObject.fromObject(userInfo); //将字符串{“id”:1} renderJson(json); } } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } }AESUtil.javaimport org.bouncycastle.jce.provider.BouncyCastleProvider;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import javax.crypto.spec.IvParameterSpec;import javax.crypto.spec.SecretKeySpec;import java.security.*;public class AESUtil { public static final AESUtil instance = new AESUtil(); public static boolean initialized = false; /** * AES解密 * @param content 密文 * @return * @throws InvalidAlgorithmParameterException * @throws NoSuchProviderException */ public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException { initialize(); try { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); Key sKeySpec = new SecretKeySpec(keyByte, "AES"); cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化 byte[] result = cipher.doFinal(content); return result; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (NoSuchProviderException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static void initialize(){ if (initialized) return; Security.addProvider(new BouncyCastleProvider()); initialized = true; } //生成iv public static AlgorithmParameters generateIV(byte[] iv) throws Exception{ AlgorithmParameters params = AlgorithmParameters.getInstance("AES"); params.init(new IvParameterSpec(iv)); return params; } }感谢你能够认真阅读完这篇文章,希望小编分享的“微信小程序中用户数据解密的示例分析”这篇文章对大家有帮助,同时也希望大家多多支持辰讯云,关注辰讯云资讯频道,更多相关知识等着你来学习!...
小编给大家分享一下微信小程序中如何动态显示项目倒计时效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、一般我们说的显示秒杀都是指的单条数据,循环我没做。效果:2、wxml代码:<p><block wx:if="{{total_micro_second<=0}}">剩余时间:已经截止</block><block wx:if="{{clock!='已经截止'}}">剩余时间:{{clock}}</block></p>3、.js文件代码:function countdown(that) { var EndTime = that.data.end_time || []; var NowTime = new Date().getTime(); var total_micro_second = EndTime - NowTime || []; console.log('剩余时间:' + total_micro_second); // 渲染倒计时时钟 that.setData({ clock: dateformat(total_micro_second) }); if (total_micro_second <= 0) { that.setData({ clock: "已经截止" }); //return; } setTimeout(function () { total_micro_second -= 1000; countdown(that); } , 1000) } // 时间格式化输出,如11:03 25:19 每1s都会调用一次 function dateformat(micro_second) { // 总秒数 var second = Math.floor(micro_second / 1000); // 天数 var day = Math.floor(second/3600/24); // 小时 var hr = Math.floor(second/3600%24); // 分钟 var min = Math.floor(second/60%60); // 秒 var sec = Math.floor(second%60); return day + "天" + hr + "小时" + min + "分钟" + sec+"秒"; } Page({ /** * 页面的初始数据 */ data: { id:'', result:[], end_time:'', clock:'' },/** * 生命周期函数--监听页面加载 */ onLoad: function (options) { var that = this; wx.request({ url: 'https://m.******.com/index.php/Home/Xiaoxxf/activity_detail?a_id='+options.id,//不含富文本html data: {}, method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT header: { 'Content-Type': 'application/json' }, success: function (res) { that.setData({ common: res.data, //一维数组,全部数据 end_time: res.data.end_time //项目截止时间,时间戳,单位毫秒 }) console.log(that.data.common); console.log('结束时间:' + that.data.end_time); }, fail: function (res) { }, complete: function (res) { }, }), //调用上面定义的递归函数,一秒一刷新时间 countdown(that); },以上是“微信小程序中如何动态显示项目倒计时效果”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注辰讯云资讯频道!...
这篇文章给大家分享的是有关微信小程序中如何实现数量加减功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。我们在购买宝贝的时候,购物的数量,经常是我们需要使用的,如下所示:在宝贝详情页里:在购物车里:现在就为大家介绍这个小组件,在小程序中,该如何去写下图为本项目的图:wxml:<!-- 主容器 --> <view class="stepper"> <!-- 减号 --> <text class="{{minusStatus}}" bindtap="bindMinus">-</text> <!-- 数值 --> <input type="number" bindchange="bindManual" value="{{num}}" /> <!-- 加号 --> <text class="normal" bindtap="bindPlus">+</text> </view>wxss:/*全局样式*/ page { padding: 20px 0; } /*主容器*/ .stepper { width: 80px; height: 26px; /*给主容器设一个边框*/ border: 1px solid #ccc; border-radius: 3px; margin:0 auto; } /*加号和减号*/ .stepper text { width: 19px; line-height: 26px; text-align: center; float: left; } /*数值*/ .stepper input { width: 40px; height: 26px; float: left; margin: 0 auto; text-align: center; font-size: 12px; /*给中间的input设置左右边框即可*/ border-left: 1px solid #ccc; border-right: 1px solid #ccc; } /*普通样式*/ .stepper .normal{ color: black; } /*禁用样式*/ .stepper .disabled{ color: #ccc; }js:Page({ data: { // input默认是1 num: 1, // 使用data数据对象设置样式名 minusStatus: 'disabled' }, /* 点击减号 */ bindMinus: function() { var num = this.data.num; // 如果大于1时,才可以减 if (num > 1) { num --; } // 只有大于一件的时候,才能normal状态,否则disable状态 var minusStatus = num <= 1 ? 'disabled' : 'normal'; // 将数值与状态写回 this.setData({ num: num, minusStatus: minusStatus }); }, /* 点击加号 */ bindPlus: function() { var num = this.data.num; // 不作过多考虑自增1 num ++; // 只有大于一件的时候,才能normal状态,否则disable状态 var minusStatus = num < 1 ? 'disabled' : 'normal'; // 将数值与状态写回 this.setData({ num: num, minusStatus: minusStatus }); }, /* 输入框事件 */ bindManual: function(e) { var num = e.detail.value; // 将数值与状态写回 this.setData({ num: num }); } })运行结果:感谢各位的阅读!关于“微信小程序中如何实现数量加减功能”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!...