centos 下 nginx 使用了 HTTPs,网页访问不了

周一之前 https 可以正常访问,周一之后就不行。问了阿里云那边,阿里云那里可以正常访问。服务器端口都开放了,没有防火墙。域名由于法人更换,有段时间是不行的。现在 80 端口可以访问,就是 443 端口出问题了。切换端口也可以。这是什么问题啊?

tomwen 1
tomwen 2019-12-31 09:55:11 +08:00
域名能发出来看看吗?
首先端口是不是开了?不能访问是浏览器阻止了还是直接就打不开?是不是证书过期或者自制证书?
guanganqishi 2
guanganqishi 2019-12-31 10:21:35 +08:00 ❤️ 1
@tomwen kubao.360reborn.com:8443 弄了个 8443 端口可以访问 https://kubao.360reborn.com 443 端口不能访问
证书是昨天弄了新的,还是不行。浏览器显示的是连接已重置
sujin190 3
sujin190 2019-12-31 10:52:30 +08:00
香港阿里云的话,一直都有这个问题啊,tsl 连接会被阻断,过几分钟又正常了
guanganqishi 4
guanganqishi 2019-12-31 11:01:44 +08:00
@sujin190 不是香港的,服务器在杭州
ChicC 5
ChicC 2019-12-31 11:04:45 +08:00
配置问题咯
guanganqishi 6
guanganqishi 2019-12-31 11:08:26 +08:00
@ChicC
server {
listen 443 ssl http2;
listen [::]:443 ssl;
server_name *.360reborn.com;
charset utf-8;
access_log logs/kubao.https.access.log main;
error_log logs/kubao.https.error.log error;

index index.php index.html index.htm;

ssl on;
ssl_certificate /usr/local/nginx/ssh/360reborn.pem;
ssl_certificate_key /usr/local/nginx/ssh/360reborn.key;

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;

location / {
root /var/www/kubao/web;
index index.php index.html index.htm;
if (!-e $request_filename) {
rewrite ^(.*)$ /index.php?s=$1 last;
break;
}
}

error_page 404 /404.html;

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

location ~ \.php$ {
root /var/www/kubao/web;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

}

是这样的配置
sujin190 7
sujin190 2019-12-31 11:17:49 +08:00
看了下,tls 就建立不成功,客户端发送 client hello 之后连接被服务器重置了,但是不发送域名是可以成功建立连接的,所以要么是域名备案问题,要么是防火墙有特殊配置,实在不行也可以升级下 nginx 和 openssl 试试
sujin190 8
sujin190 2019-12-31 11:19:08 +08:00
证书和加密套件配置都没有问题,如果域名备案没有问题,防火墙也是正常的,那么 nginx 有 bug 也是可能的
guanganqishi 9
guanganqishi 2019-12-31 11:43:46 +08:00
@sujin190 嗯嗯 好的 谢谢 我再看看吧
sujin190 10
sujin190 2019-12-31 11:53:08 +08:00
看非 443 可以正常用而且是服务器 rst,所以大概率是域名合规问题,实在找不出啥问题可以给阿里云提工单问问

noqwerty 2019-12-31 12:02:30 +08:00 via Android
我这边可以直接打开你的链接啊,浏览器清一下缓存看看?
venhow 12
venhow 2019-12-31 14:33:46 +08:00
没有加载到证书啊
ChicC 13
ChicC 2019-12-31 14:42:46 +08:00
ssl_certificate /usr/local/nginx/ssh/360reborn.pem;
@guanganqishi

是配置 pem 文件吗?不是 crt 吗
justfly 14
justfly 2019-12-31 14:49:37 +08:00
https://47.98.153.226/ 没问题,也能达到正确的证书,所以倾向于证书没啥问题,但是使用域名就有问题,怀疑防火墙或者 SNI 相关逻辑,看看 nginx 的错误日志。
privil 15
privil 2019-12-31 15:10:37 +08:00
本机配置一下 host 域名指向 127.0.0.1 然后 curl 试一下行不行。
privil 16
privil 2019-12-31 15:11:25 +08:00
服务器本机。
jeblur 17
jeblur 2019-12-31 15:16:41 +08:00
正常打开
whnzy 18
whnzy 2020-01-03 16:38:24 +08:00
法人变更,是需要更新备案信息的,因为 2020 年,TLSv1.0 和 TLSv1.1 就不支持了,TLSv1.2 是支持 SNI 的,很容易被监测出来的。
我 ICP 查询,你们是备案的,但是有可能是因为没有更新备案信息。
每个浏览器对 TLSv1.0 和 TLSv1.1 的禁用时间不同,就会导致不同的浏览器会有不同的表现。
希望能帮到你。

python爬虫–协程

python爬虫–协程
基本知识
event_loop:事件循环,相当于一个无限循环,我们可以把一些函数注册到这个事件循环上,当满足某些条件的时候,函数就会被循环执行。
coroutine:携程对象,我们可以将携程对象注册到事件循环中,它会被时间循环调用。我们可以使用async关键字来定义一个方法,这个方法在调用时不会被立即执行,而是返回一个协程对象。
task:任务,它是对协程对象的进一步封装, 包含了任务的各个状态。
future:代表将来执行或还没有执行的任务,实际上和task 没有本质区别。
async定义-个协程.
await用来挂起阻塞方法的执行。
协程的基本使用
import asyncio

async def request(url):
print(‘正在请求的url是:’,url)
print(‘请求成功:’,url)
#async修饰的函数,调用之后返回的一个协程对象
c = request(‘www.baidu.com’)

# #创建一个事件循环对象
# loop = asyncio.get_event_loop()
#
# #将携程对象注册到loop中,然后启动loop
# loop.run_until_complete(c)

# #task的使用
# loop = asyncio.get_event_loop()
# #基于loop创建一个task对象
# task = loop.create_task(c)
# print(task)
# loop.run_until_complete(task)
# print(task)

#future的使用
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(c)
print(task)
loop.run_until_complete(task)
print(task)

多任务协程实现
import asyncio
import time

async def request(url):
print(‘正在请求的url是:’,url)
#在异步协程中如果出现同步模块相关的代码,那么就无法实现异步
#time.sleep(2)
await asyncio.sleep(2)
print(‘请求成功:’,url)
#async修饰的函数,调用之后返回的一个协程对象
start = time.time()
urls = {
‘www.123.com’,
‘www.234.com’,
‘www.345.com’
}
#存放多个任务对象
stask = []
for url in urls:
c = request(url)
task = asyncio.ensure_future(c)
stask.append(task)
loop = asyncio.get_event_loop()

loop.run_until_complete(asyncio.wait(stask))

print(time.time()-start)

多任务协程异步实现
在进行多任务协程实现前,还需要建立一个简单的本地http服务

from flask import Flask
import time

app = Flask(__name__)

@app.route(‘/azb’)
def index_azb():
time.sleep(2)
return ‘Hello azb’

@app.route(‘/xx’)
def index_xx():
time.sleep(2)
return ‘Hello xx’

@app.route(‘/hh’)
def index_hh():
time.sleep(2)
return ‘Hello hh’

if __name__ == ‘__main__’:
app.run(threaded=True)

%title插图%num
实现

import requests,asyncio,time

start = time.time()
urls = [
‘http://127.0.0.1:5000/azb’,’http://127.0.0.1:5000/xx’,’http://127.0.0.1:5000/hh’
]

async def get_page(url):
print(‘正在下载’,url)
#request是基于同步,必须使用基于异步的网络请求模块
response = requests.get(url=url)
print(‘下载成功!’,url)

tasks = []

for url in urls:
c = get_page(url)
task = asyncio.ensure_future(c)
tasks.append(task)

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print(‘总耗时’,time.time()-start)
%title插图%num

aiohttp模块引入
import requests,asyncio,time,aiohttp

start = time.time()
urls = [
‘http://127.0.0.1:5000/azb’,’http://127.0.0.1:5000/xx’,’http://127.0.0.1:5000/hh’
]

async def get_page(url):
async with aiohttp.ClientSession() as session:
async with await session.get(url) as response:
#text()返回字符串形式的响应数据
#read()返回的二进制形式的响应数据
#json()返回的就是json对象
#获取响应数据操作之前一定要使用await进行手动挂起

page_text = await response.text()
print(page_text)

tasks = []

for url in urls:
c = get_page(url)
task = asyncio.ensure_future(c)
tasks.append(task)

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(tasks))

print(‘总耗时’,time.time()-start)%title插图%num

 

协程还是没有理解

Android Fragment 真正的完全解析(上)

自从Fragment出现,曾经有段时间,感觉大家谈什么都能跟Fragment谈上关系,做什么都要问下Fragment能实现不~~~哈哈,是不是有点过~~~

本篇博客力求为大家说明Fragment如何产生,什么是Fragment,Fragment生命周期,如何静态和动态的使用Fragment,Fragment回退栈,Fragment事务;以及Fragment的一些特殊用途,例如:没有布局的Fragment有何用处?Fragment如何与Activity交互?Fragment如何创建对话框?Fragment如何与ActionBar集成等等。

1、Fragment的产生与介绍

Android运行在各种各样的设备中,有小屏幕的手机,超大屏的平板甚至电视。针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套App,然后拷贝一份,修改布局以适应平板神马超级大屏的。难道无法做到一个App可以同时适应手机和平板么,当然了,必须有啊。Fragment的出现就是为了解决这样的问题。你可以把Fragment当成Activity的一个界面的一个组成部分,甚至Activity的界面可以完全有不同的Fragment组成,更帅气的是Fragment拥有自己的生命周期和接收、处理用户的事件,这样就不必在Activity写一堆控件的事件处理的代码了。更为重要的是,你可以动态的添加、替换和移除某个Fragment。

2、Fragment的生命周期

Fragment必须是依存与Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。官网这张图很好的说明了两者生命周期的关系:

%title插图%num

可以看到Fragment比Activity多了几个额外的生命周期回调方法:
onAttach(Activity)
当Fragment与Activity发生关联时调用。
onCreateView(LayoutInflater, ViewGroup,Bundle)
创建该Fragment的视图
onActivityCreated(Bundle)
当Activity的onCreate方法返回时调用
onDestoryView()
与onCreateView想对应,当该Fragment的视图被移除时调用
onDetach()
与onAttach相对应,当Fragment与Activity关联被取消时调用
注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现,

3、静态的使用Fragment

嘿嘿,终于到使用的时刻了~~

这是使用Fragment*简单的一种方式,把Fragment当成普通的控件,直接写在Activity的布局文件中。步骤:

1、继承Fragment,重写onCreateView决定Fragemnt的布局

2、在Activity中声明此Fragment,就当和普通的View一样

下面展示一个例子(我使用2个Fragment作为Activity的布局,一个Fragment用于标题布局,一个Fragment用于内容布局):

TitleFragment的布局文件:

  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
  3. android:layout_width=“match_parent”
  4. android:layout_height=“45dp”
  5. android:background=“@drawable/title_bar” >
  6. <ImageButton
  7. android:id=“@+id/id_title_left_btn”
  8. android:layout_width=“wrap_content”
  9. android:layout_height=“wrap_content”
  10. android:layout_centerVertical=“true”
  11. android:layout_marginLeft=“3dp”
  12. android:background=“@drawable/showleft_selector” />
  13. <TextView
  14. android:layout_width=“fill_parent”
  15. android:layout_height=“fill_parent”
  16. android:gravity=“center”
  17. android:text=“我不是微信”
  18. android:textColor=“#fff”
  19. android:textSize=“20sp”
  20. android:textStyle=“bold” />
  21. </RelativeLayout>

TitleFragment

  1. package com.zhy.zhy_fragments;
  2. import android.app.Fragment;
  3. import android.os.Bundle;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.view.ViewGroup;
  8. import android.widget.ImageButton;
  9. import android.widget.Toast;
  10. public class TitleFragment extends Fragment
  11. {
  12. private ImageButton mLeftMenu;
  13. @Override
  14. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  15. Bundle savedInstanceState)
  16. {
  17. View view = inflater.inflate(R.layout.fragment_title, container, false);
  18. mLeftMenu = (ImageButton) view.findViewById(R.id.id_title_left_btn);
  19. mLeftMenu.setOnClickListener(new OnClickListener()
  20. {
  21. @Override
  22. public void onClick(View v)
  23. {
  24. Toast.makeText(getActivity(),
  25. “i am an ImageButton in TitleFragment ! “,
  26. Toast.LENGTH_SHORT).show();
  27. }
  28. });
  29. return view;
  30. }
  31. }

同理还有ContentFragment的其布局文件:

  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
  3. android:layout_width=“match_parent”
  4. android:layout_height=“match_parent”
  5. android:orientation=“vertical” >
  6. <TextView
  7. android:layout_width=“fill_parent”
  8. android:layout_height=“fill_parent”
  9. android:gravity=“center”
  10. android:text=“使用Fragment做主面板”
  11. android:textSize=“20sp”
  12. android:textStyle=“bold” />
  13. </LinearLayout>

 

  1. package com.zhy.zhy_fragments;
  2. import android.app.Fragment;
  3. import android.os.Bundle;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. public class ContentFragment extends Fragment
  8. {
  9. @Override
  10. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  11. Bundle savedInstanceState)
  12. {
  13. return inflater.inflate(R.layout.fragment_content, container, false);
  14. }
  15. }

MainActivity

  1. package com.zhy.zhy_fragments;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.view.Window;
  5. public class MainActivity extends Activity
  6. {
  7. @Override
  8. protected void onCreate(Bundle savedInstanceState)
  9. {
  10. super.onCreate(savedInstanceState);
  11. requestWindowFeature(Window.FEATURE_NO_TITLE);
  12. setContentView(R.layout.activity_main);
  13. }
  14. }

Activity的布局文件:

  1. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
  2. xmlns:tools=“http://schemas.android.com/tools”
  3. android:layout_width=“match_parent”
  4. android:layout_height=“match_parent” >
  5. <fragment
  6. android:id=“@+id/id_fragment_title”
  7. android:name=“com.zhy.zhy_fragments.TitleFragment”
  8. android:layout_width=“fill_parent”
  9. android:layout_height=“45dp” />
  10. <fragment
  11. android:layout_below=“@id/id_fragment_title”
  12. android:id=“@+id/id_fragment_content”
  13. android:name=“com.zhy.zhy_fragments.ContentFragment”
  14. android:layout_width=“fill_parent”
  15. android:layout_height=“fill_parent” />
  16. </RelativeLayout>

是不是把Fragment当成普通的View一样声明在Activity的布局文件中,然后所有控件的事件处理等代码都由各自的Fragment去处理,瞬间觉得Activity好干净有木有~~代码的可读性、复用性以及可维护性是不是瞬间提升了~~~下面看下效果图:

%title插图%num

4、动态的使用Fragment

上面已经演示了,*简单的使用Fragment的方式~下面介绍如何动态的添加、更新、以及删除Fragment

为了动态使用Fragment,我们修改一下Actvity的布局文件,中间使用一个FrameLayout,下面添加四个按钮~~~嘿嘿~~不是微信的按钮- -!

  1. <RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
  2. xmlns:tools=“http://schemas.android.com/tools”
  3. android:layout_width=“match_parent”
  4. android:layout_height=“match_parent” >
  5. <fragment
  6. android:id=“@+id/id_fragment_title”
  7. android:name=“com.zhy.zhy_fragments.TitleFragment”
  8. android:layout_width=“fill_parent”
  9. android:layout_height=“45dp” />
  10. <include
  11. android:id=“@+id/id_ly_bottombar”
  12. android:layout_width=“fill_parent”
  13. android:layout_height=“55dp”
  14. android:layout_alignParentBottom=“true”
  15. layout=“@layout/bottombar” />
  16. <FrameLayout
  17. android:id=“@+id/id_content”
  18. android:layout_width=“fill_parent”
  19. android:layout_height=“fill_parent”
  20. android:layout_above=“@id/id_ly_bottombar”
  21. android:layout_below=“@id/id_fragment_title” />
  22. </RelativeLayout>

底部四个按钮的布局就不贴了,到时看效果图就明白了~~

下面主Activity

  1. package com.zhy.zhy_fragments;
  2. import android.app.Activity;
  3. import android.app.FragmentManager;
  4. import android.app.FragmentTransaction;
  5. import android.os.Bundle;
  6. import android.view.View;
  7. import android.view.View.OnClickListener;
  8. import android.view.Window;
  9. import android.widget.LinearLayout;
  10. public class MainActivity extends Activity implements OnClickListener
  11. {
  12. private LinearLayout mTabWeixin;
  13. private LinearLayout mTabFriend;
  14. private ContentFragment mWeixin;
  15. private FriendFragment mFriend;
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState)
  18. {
  19. super.onCreate(savedInstanceState);
  20. requestWindowFeature(Window.FEATURE_NO_TITLE);
  21. setContentView(R.layout.activity_main);
  22. // 初始化控件和声明事件
  23. mTabWeixin = (LinearLayout) findViewById(R.id.tab_bottom_weixin);
  24. mTabFriend = (LinearLayout) findViewById(R.id.tab_bottom_friend);
  25. mTabWeixin.setOnClickListener(this);
  26. mTabFriend.setOnClickListener(this);
  27. // 设置默认的Fragment
  28. setDefaultFragment();
  29. }
  30. private void setDefaultFragment()
  31. {
  32. FragmentManager fm = getFragmentManager();
  33. FragmentTransaction transaction = fm.beginTransaction();
  34. mWeixin = new ContentFragment();
  35. transaction.replace(R.id.id_content, mWeixin);
  36. transaction.commit();
  37. }
  38. @Override
  39. public void onClick(View v)
  40. {
  41. FragmentManager fm = getFragmentManager();
  42. // 开启Fragment事务
  43. FragmentTransaction transaction = fm.beginTransaction();
  44. switch (v.getId())
  45. {
  46. case R.id.tab_bottom_weixin:
  47. if (mWeixin == null)
  48. {
  49. mWeixin = new ContentFragment();
  50. }
  51. // 使用当前Fragment的布局替代id_content的控件
  52. transaction.replace(R.id.id_content, mWeixin);
  53. break;
  54. case R.id.tab_bottom_friend:
  55. if (mFriend == null)
  56. {
  57. mFriend = new FriendFragment();
  58. }
  59. transaction.replace(R.id.id_content, mFriend);
  60. break;
  61. }
  62. // transaction.addToBackStack();
  63. // 事务提交
  64. transaction.commit();
  65. }
  66. }

可以看到我们使用FragmentManager对Fragment进行了动态的加载,这里使用的是replace方法~~下一节我会详细介绍FragmentManager的常用API。

注:如果使用Android3.0以下的版本,需要引入v4的包,然后Activity继承FragmentActivity,然后通过getSupportFragmentManager获得FragmentManager。不过还是建议版Menifest文件的uses-sdk的minSdkVersion和targetSdkVersion都改为11以上,这样就不必引入v4包了。

代码中间还有两个Fragment的子类,ContentFragment上面已经见过,FriendFragment其实类似:

  1. package com.zhy.zhy_fragments;
  2. import android.app.Fragment;
  3. import android.os.Bundle;
  4. import android.view.LayoutInflater;
  5. import android.view.View;
  6. import android.view.ViewGroup;
  7. public class FriendFragment extends Fragment
  8. {
  9. @Override
  10. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  11. Bundle savedInstanceState)
  12. {
  13. return inflater.inflate(R.layout.fragment_friend, container, false);
  14. }
  15. }

效果图:

%title插图%num

可以看到很好的实现了效果,有兴趣可以看看。

5、Fragment家族常用的API

Fragment常用的三个类:

android.app.Fragment 主要用于定义Fragment

android.app.FragmentManager 主要用于在Activity中操作Fragment

android.app.FragmentTransaction 保证一些列Fragment操作的原子性,熟悉事务这个词,一定能明白~

a、获取FragmentManage的方式:

getFragmentManager() // v4中,getSupportFragmentManager

b、主要的操作都是FragmentTransaction的方法

FragmentTransaction transaction = fm.benginTransatcion();//开启一个事务

transaction.add() 

往Activity中添加一个Fragment

transaction.remove()

从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。

transaction.replace()

使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体~

transaction.hide()

隐藏当前的Fragment,仅仅是设为不可见,并不会销毁

transaction.show()

显示之前隐藏的Fragment

detach()

会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。

attach()

重建view视图,附加到UI上并显示。

transatcion.commit()//提交一个事务

注意:常用Fragment的哥们,可能会经常遇到这样Activity状态不一致:State loss这样的错误。主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用。

上述,基本是操作Fragment的所有的方式了,在一个事务开启到提交可以进行多个的添加、移除、替换等操作。

值得注意的是:如果你喜欢使用Fragment,一定要清楚这些方法,哪个会销毁视图,哪个会销毁实例,哪个仅仅只是隐藏,这样才能更好的使用它们。

a、比如:我在FragmentA中的EditText填了一些数据,当切换到FragmentB时,如果希望会到A还能看到数据,则适合你的就是hide和show;也就是说,希望保留用户操作的面板,你可以使用hide和show,当然了不要使劲在那new实例,进行下非null判断。

b、再比如:我不希望保留用户操作,你可以使用remove(),然后add();或者使用replace()这个和remove,add是相同的效果。

c、remove和detach有一点细微的区别,在不考虑回退栈的情况下,remove会销毁整个Fragment实例,而detach则只是销毁其视图结构,实例并不会被销毁。那么二者怎么取舍使用呢?如果你的当前Activity一直存在,那么在不希望保留用户操作的时候,你可以优先使用detach。

上述已经介绍完成了Fragment常用的一些方法,相信看完,大家一定清楚了Fragment的产生理由,以及如何使用Fragment,再根据API的讲解,也能明白,曾经为何觉得Fragment会出现一些列乱七八槽的问题,终究是因为没有弄清楚其生命周期。

由于篇幅原因,剩下的内容留到下一篇了。在下一篇,会介绍:

1、如何管理Fragment回退栈

2、Fragment如何与Activity交互

3、Fragment与Activity交互的*佳实践

4、没有视图的Fragment的用处

5、使用Fragment创建对话框

6、如何与ActionBar,MenuItem集成等~~

 

会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。

Ivanti Neurons™神经元:远程边缘设备实现自主、自动、自助管理

打造可愈合的自主边缘(Autonomous Edge),让远程工作人员提前结合上下文,实现远程边缘设备的自助管理。

近日,致力于通过统一IT为企业用户提供更加高效安全数字化工作场所的Ivanti发布了基于深度学习技术的超级自动化平台——Ivanti Neurons™ 神经元。

该平台赋予企业自主愈合和保护边缘设备的能力,并重新诠释了为*终用户提供IT自助服务的理念。

通过一系列智能应用,*终用户可自主进行检测和修复边缘设备,企业IT团队的服务效率将获得大幅提升,管理成本显著减少。

目前,已采用Ivanti Neurons™ 神经元的企业可将意外停运时间减少63%,部署安全升级的时间缩短88%,并在用户上报之前解决多达80%的端点设备问题。

%title插图%num

Ivanti Neurons™神经元的全新上线,标志着Ivanti进一步实现其预见性和前瞻性,即打造超级自动化平台,帮助企业用户有效地应对日益繁复的设备、数据和远程工作人员的管理问题,以及层出不穷的安全威胁,助力企业IT管理从基础的自动化转型,走向成熟的超级自动化,为远程工作人员提供可愈合的自主体验,帮助其提前结合自身状况,实现远程边缘设备的自助管理。

Ivanti执行副总裁兼首席产品总监Nayaki Nayyar表示:“随着远程工作模式成为下一个常态,Ivanti Neurons™ 神经元不仅为企业提供了自主修复和保护端点设备的能力,还为员工提供了 ‘随时随地工作’的无缝体验。借助可自主检修和保护边缘端点设备的智能应用,IT部门将实现‘及早发现,及时解决问题’的工作目标。”

金斯顿大学技术服务负责人Daniel Bolton表示:“Ivanti Neurons™神经元提供主动式监测,让我们随时掌握各设备电池的使用情况及寿命,节省了大量资产采购和维修成本。而且,Ivanti Neurons™神经元能在短时间内为技术部门提供动态信息,帮助我们做出更合理的决策,确保在校员工和学生高效地完成工作及学习。”

Ivanti Neurons™超级自动化平台,可为企业及组织提供多项功能,包括:

· Ivanti Neurons™ for Edge Intelligence边缘设备智能化: 这项基于自然语言处理技术(NLP)的功能,将帮助IT团队快速查询所有边缘设备,在短时间内获取内部整体信息;它还拥有基于传感器的架构,可以帮助企业迅速了解边缘设备的运营环境,实时清点资产,并做好安全配置。

· Ivanti Neurons™ for Healing自我治疗:该功能可提供一系列智能应用,可主动检测、诊断和自动修复端点设备的配置问题、合规问题及安全问题,实现常规任务自动化,为打造真正的IT自愈合环境铺平道路,大大提升效率并缩减成本,改善用户体验。

· Ivanti Neurons™ for Discovery发现:该功能可在短时间内提供准确而实用的资产信息,通过主动扫描、被动扫描和第三方连接器,提供实时的可视化功能。这些规范化的软硬件资产清点数据、软件使用信息以及实用的洞察,有助于高效地配置管理数据库和资产管理数据库。

· Ivanti Neurons™ Workspace工作空间:该功能基于实时数据,提供了从设备、用户,到应用程序和服务的360度全方位视图,可帮助一线IT人员解决原本需要向专家上报的问题,消除问题上报带来的复杂性,同时缩短等待时间并降低上报成本,有助于加快解决*终用户的问题,大幅提高工作效率。

如今云服务器大行其道的时代,如何选购物理服务器?

用途:公司内部系统使用

网上找了一圈,也没发现啥有价值的选购指南,不知道该看哪些参数等等。
特来问问各位大佬们!

locoz 2020-01-11 01:50:41 +08:00 via Android
具体需求呢…内部系统消耗哪方面资源比较多总得搞清楚吧?要哪方面性能高也得搞清楚吧?搞清楚了之后无非就是对症下药堆配置了。
CPU 现在的话可以试试 AMD…香到爆炸…
mashaofeixxx 2
mashaofeixxx 2020-01-11 08:39:50 +08:00
对配置要求高吗 nuc 能满足吗?
s609926202 3
s609926202 2020-01-11 08:40:45 +08:00 via iPhone
@locoz @mashaofeixxx
就是 erp 系统
mashaofeixxx 4
mashaofeixxx 2020-01-11 08:43:33 +08:00
@s609926202 我前两天给客户使用 nuc 部署了 用友 要不咱俩聊聊 我做 nuc 服务器这块 提供公网解决方案
我的 wx: d2cc67aa8cD66D1b 不需要解密,直接加,加个好友聊聊.
ladypxy 5
ladypxy 2020-01-11 09:02:14 +08:00 via iPhone
这种问题有啥问的意义么
物理服务器就那几家,ibm HP dell,直接买就好了
s609926202 6
s609926202 2020-01-11 09:29:51 +08:00 via iPhone
@ladypxy 货比三家,买*合适的
murmur 7
murmur 2020-01-11 10:04:10 +08:00
机房用就选服务好的,一个电话就能叫上门的,不过原厂服务贵到坑 b 就是了,自用就学翼王这种自己组配件
反正 2u 的机箱基本上 ATX 组件可以随便用,不存在组装问题,而且因为体积大所以风扇也比较柔和
stoneabc 8
stoneabc 2020-01-11 11:30:36 +08:00
小公司没严格要求的话,可以找找各大云厂商 3 年淘汰的旧机器。。
venster 9
venster 2020-01-11 11:37:23 +08:00 via Android
记住:别买联想,下个驱动还得到美国站去下载,中国站找一天都不一定找得到。其他的戴尔惠普直接联系网站销售就行了。
abbottcn 10
abbottcn 2020-01-11 12:15:04 +08:00 via iPhone
可能和大家的用途差太多。做 CPU 密集型计算,组装的服务器。放机房的。服务器主板,有个毛病,启动贼慢。根据需求,配置非常灵活,比浪潮的整机便宜特别多。

NerverLibis 2020-01-11 12:32:20 +08:00 via iPhone
@venster 就算是笔记本也不能碰联想,除非有回扣
herozzm 12
herozzm 2020-01-11 12:39:57 +08:00
@ladypxy +1
328730311 13
328730311 2020-01-11 13:51:04 +08:00
dell r740 2u 8 核*2/16g*4/1.2t 10k 2.5 寸 *4 ( raid5 )/idrac 远控 /单电源,(或者塔式服务 dell t640 )参考这个配置。如果预算有限,可以用刚停产的 r730 或者 t630。
MeteorCat 14
MeteorCat 2020-01-11 13:54:40 +08:00 via Android
我买了专线宽带+gen8+gen10 自己搭服务器,实际上*开始用阿里云服务器现在 1G2M 带宽续费一年 1500 一计算还不如自己去接入专线买个高配置主机
594duck 15
594duck 2020-01-12 15:36:42 +08:00 via iPhone
10 年运维在这里
s609926202 16
s609926202 2020-01-12 16:42:11 +08:00 via iPhone
@594duck 请问本地物理服务器除了专线固定 ip 还有其他办法实现公网访问吗?
594duck 17
594duck 2020-01-12 20:34:33 +08:00 via iPhone
@s609926202

你是指公网访问你的服务器,可以用的电脑上,(动态的 dns )防火墙都带一些的,映射下就好。但是在今天的国内线路里边很痛苦。运营商会封锁

ntp crontab同步集群服务器时间

实际情形:当服务器非常多的时候,比如1000台服务器,要求每天或者某个时间点开启服务,或者执行一项job。

配置过程

首先检查 ntp 命令是否安装

没有安装则安装一下 yum install ntp ntpdate -y

为了方便切换到root用户执行

su root

编辑配置文件

vim /etc/ntp.conf

如图

%title插图%num

在文件末尾添加

server 127.127.1.0

fudge 127.127.1.0 stratum 10

解释:

1、去掉注释,是允许192.168.1.0 网段的服务器来获取时间

2、添加注释,禁用使用其他网段服务器的时间

3、当该节点丢失网络连接,依然可以采用本地时间作为时间服务器为集群中的其他节点提供时间同步

vim /etc/sysconfig/ntpd

添加以后代码

SYNC_HWCLOCK=yes

启动ntp服务器
首先查看ntp服务器的状态

service ntpd status

如图

%title插图%num

启动ntp服务器

service ntpd start

%title插图%num

设置开机自启:chkconfig ntpd on

*后检测是否配置成功了
登录到其他服务器上(在一个网段内的)

上面我是将hadoop112作为ntp服务器

下面我进入hadoop113服务器 (root身份)

输入crontab -e

添加代码

*/1 * * * * /usr/sbin/ntpdate hadoop112

意思是每隔1分钟同步一次时间

%title插图%num

退出编辑后按照下面的查看时间,修改时间。然后等待一分钟查看一下时间有没有自动修改回来

%title插图%num

扩展知识:

crontab讲解

在上方出现了crontab -e

并且添加了一行代码,下面进行讲解

*/1 * * * * /usr/sbin/ntpdate hadoop112

基本格式 :
*      *   *    *   *  command
分 时 日 月 周   命令

iOS14,删个 APP 需要点三次,苹果公司是怎么想的?

才发现在资源库里,长按图标,弹出的菜单里选择删除,iOS14 就问一次,点确定就删除了。

45 条回复    2021-03-27 10:33:47 +08:00
mh
    1

mh   22 小时 36 分钟前

不是两次么
whileFalse
    2

whileFalse   22 小时 35 分钟前   ❤️ 1

你删除 APP 的频率有多高?
hash
    3

hash   22 小时 34 分钟前   ❤️ 1

*后一次确认确实意义非常有限
hlobo
    4

hlobo   22 小时 33 分钟前 via Android   ❤️ 30

少用那些,装上用 15 分钟就删掉的 app,注意身体
stark123
    5

stark123   22 小时 30 分钟前

@whileFalse 我才转到 iOS 上。下载了很多 APP 试验,不好的就都删掉。今天删了 40 多个了。
xnotepad
    6

xnotepad   22 小时 29 分钟前

装个 APP 还得按两次关闭按钮呢。这样一比,是不是觉得你那个三次点击也就没啥了。
superrichman
    7

superrichman   22 小时 26 分钟前 via iPhone

你就当多点一下是帮你清空数据好了,ios 不会跟安卓一样删了 app 还留一堆乱七八糟的文件夹
MidAutumnMoon
    8

MidAutumnMoon   22 小时 23 分钟前 via iPhone

确实现在的操作不如以前那样自然,这方面 iOS 就像走了倒车似的( imo )
finab
    9

finab   22 小时 20 分钟前   ❤️ 1

嘿嘿,我可以压缩到俩次~
按住 弹出菜单后手指滑到删除按钮再松开,再点确认~
deplives
    10

deplives   22 小时 19 分钟前 via iPhone   ❤️ 3

两次吧你就要问 为啥删除前不确认一次,万一误删除咋办,三次吧又问为啥还要点三次,
现在就差直接读取你脑子里的想法了,这样一次也不用点

 

dingdangnao
    11

dingdangnao   22 小时 19 分钟前

真心觉得 iOS 的某些交互需要改改了。。。比如左上角返回。。MAX 一只手根本点不到左上角。。
(尤其国内某些垃圾 app 没有左滑返回,只能点左上角

iOS 的主界面的图标,iPhone 12 Pro Max 只比 iPhone 5 多了一排。。。傻大笨的感觉。。哎

whileFalse
    12

whileFalse   22 小时 8 分钟前

@stark123 特别想知道你是怎么样点 3 次才删除的。我都是两次。
Astrian
    13

Astrian   22 小时 2 分钟前

我猜你是通过按住图标会出现 context menu 里面的删除按钮来删除 app……
弹出 context menu 继续按住就会变成经典的抖图标
flineqaq
    14

flineqaq   22 小时 0 分钟前 via iPhone

3 次很多么……你把发这个帖子的点击次数省下来,按 2 次的指标够用十几年了╮( ̄▽ ̄””)╭
so898
    15

so898   21 小时 47 分钟前

@dingdangnao 把 Home Indicator (底部的那个横条)往下拨动一下会有惊喜
JoJoJoJ
    16

JoJoJoJ   21 小时 46 分钟前 via iPhone

google 的 hangout,删除一条短信要按 6 次
kop1989
    17

kop1989   21 小时 41 分钟前

主要是多了一个资源库( app 抽屉)。所以要确认你是要删除 app,还是删除桌面图标。
icyalala
    18

icyalala   21 小时 31 分钟前

@mh @finab @whileFalse
两次是怎么做到的?

*种方法:
1. 按住图标出现菜单,滑动到 “移除 App”
2. 在弹出的菜单中点击 “删除 App”
3. 在弹出的菜单中点击 “删除”

第二种方法:
1. 长按图标出现抖动
2. 点左上角的减号
3. 在弹出的菜单中点击 “删除 App”
4. 在弹出的菜单中点击 “删除”

感觉这套东西都是在出现了 App 资源库之后弄得一坨补丁

safarigu
    19

safarigu   21 小时 28 分钟前

感觉现在苹果 iOS 产品做得真的挺差的,该换人换人吧?
更别提 Apple TV app 要多蹩脚有多蹩脚
stark123
    20

stark123   21 小时 25 分钟前

@JoJoJoJ 6 次,这是什么天才逻辑
minami
    21

minami   21 小时 19 分钟前   ❤️ 1

苹果公司怎么想不重要,重要的是果粉怎么想。既然果粉都不觉得是个问题,那么就不是个问题。你看是不是有种哲理在里面
wovfeng
    22

wovfeng   20 小时 32 分钟前 via iPhone   ❤️ 1

说一个小众的删除方法,还可以在 app store 更新那边左滑删除。有时候发现 app 更新了,但好像有没怎么用就顺手删掉了…
petercui
    23

petercui   20 小时 2 分钟前   ❤️ 1

@xnotepad 两次握手,三次挥手。
JHExp
    24

JHExp   19 小时 56 分钟前

开关推送不能快捷操作感觉是*困扰的
wclebb
    25

wclebb   19 小时 40 分钟前 via iPhone

长按—移除,就两次啊?
From313
    26

From313   19 小时 29 分钟前

资源库搜索列表的 App 不能直接删,我是拖拽到桌面删….
ntcydia
    27

ntcydia   19 小时 27 分钟前

在两次删除 app 这个操作上 3D touch 确实是个好功能。
dingdangnao
    28

dingdangnao   19 小时 17 分钟前

@so898 是 确实有所谓的“便捷访问”什么的,你可以去试试看 max 机型, 拇指能不能够得到屏幕一半*左边?
zbatman
    29

zbatman   17 小时 15 分钟前 via Android

是你不会用吧,苹果的设计师不比你懂手机?[狗头]
kiripeng
    30

kiripeng   17 小时 12 分钟前

苹果就是把用户当孙子,而*新的苹果手机对用户的政策是当傻子。( mac 在手我还是这么说)
minamike
    31

minamike   17 小时 0 分钟前 via iPhone

@From313 可以删的 列表里长按图标出现菜单就能删除了
appstore54321
    32

appstore54321   16 小时 44 分钟前 via iPhone

还不是你不会用.jpg

果粉怎么回事?

youcandoit
    33

youcandoit   16 小时 36 分钟前 via iPhone

@hlobo #4 这是什么梗啊……
drawstar
    34

drawstar   16 小时 4 分钟前 via iPhone

@whileFalse 每次进入贤者时间 doge
felixcode
    35

felixcode   15 小时 55 分钟前   ❤️ 1

*近学到了一个超好用的句型:

你们扪心自问一下,你真的需要只点两次就删除 APP 吗?

stark123
    36

stark123   15 小时 46 分钟前

@felixcode 不试用怎么知道是否合适。不合适难道留着过年?
hkezh
    37

hkezh   15 小时 25 分钟前 via iPhone   ❤️ 1

应该给一个资源库开关,不是所有人都喜欢
stark123
    38

stark123   15 小时 17 分钟前

@hkezh 那玩意我非常讨厌。根本用不上。
SenLief
    39

SenLief   15 小时 11 分钟前

苹果的用意是让用户形成习惯,习惯就好了,毕竟我觉得我是对的。
orangy
    40

orangy   14 小时 22 分钟前 via iPhone

@JHExp 长按消息,右上角会出现三点,点击三点,就可以管理该条消息 app 的推送设置了,你是指这个快捷操作吗??
5966
    41

5966   12 小时 33 分钟前 via iPhone

当你在 Safari 打开很多标签,想全部关闭,1,Safari 长按右下角图标,弹出,2,关闭 n 个标签页,还没有完,3,确认关闭吗?
stark123
    42

stark123   11 小时 52 分钟前

@5966 哈哈哈,这逻辑,够 2 的。
daerzei
    43

daerzei   11 小时 23 分钟前 via iPhone

我收集限免应用(下完就删)时体会到了,那个资源库确实没卵用还憨憨,以前确认一下就删了,现在点错了还得去资源库找
littlewing
    44

littlewing   11 小时 19 分钟前

@daerzei 不用真的下载吧,直接点一下,然后取消下载
rcw
    45

rcw   18 分钟前 via iPhone

可能苹果觉得你不会经常删 app

iOS开发-GCD技术

文章目录
前言
Dispatch Queue
Queue Create
Queue Release
MRC
ARC
Global Queue
如何设置QOS级别
Dispatch Set Target
dispatch_after
GCD timer
Dispatch Group
dispatch_group_notify
dispatch_group_wait
dispatch_barrier_async
dispatch_apply
dispatch_resume/dispatch_suspend
dispatch TLS
前言
对于OS X和iOS的XNU内核线程切换时,会进行上下文切换,例如CPU的寄存器等信息保存到各自路径专用的内存块中,从切换目标路径专用的内存块中,复原CPU寄存器等信息,继续执行切换路径的CPU命令行。这被称为“上下文切换”。

使用多线程的程序可以在某个线程和其他线程之间反复多次进行上下文切换,因此看上去就好像1个CPU核能够并列的执行多个线程一样。而且在具有多个CPU核的情况下,就不是“看上去像”了,而是真的提供了多个CPU核并行执行多个线程的技术。

多线程编程易发生各种问题,例如多个线程对资源的竞争,多个线程之间相互等待造成死锁,以及线程开辟消耗大量的内存等问题。

%title插图%num

多线程的优点在于能够将复杂的处理独立出来,不会阻塞主线程这种线程的执行

%title插图%num

GCD是基于XNU内核的线程技术,大大简化了多线程编程的源码。

Dispatch Queue
一般来说我们会这样异步执行一个任务

1   dispatch_async(queue,^{
2  //do your task
3  });

queue代表一个队列,在GCD中存在两种队列形式

Serial Dispatch Queue 串行队列
Concurrent Dispatch Queue 并行队列
两种队列的在于,Serial处理task是根据队列先进先出顺序执行,会保证上一个task执行完再执行下一个,而Concurrent则是并发执行,不会等上一个task执行完

%title插图%num

虽然Concurrent Dispatch Queue不用等待处理结束,可以并发执行多个task,但是其并发线程的数量却是取决于当前系统的状态。根据如下:

iOS和OS X基于Dispatch Queue中的处理数
CPU核数以及CPU负荷等当前系统的状态
来决定Concurrent Dispatch Queue中线程数量。

例如:

1    dispatch_asyc(queue,blk0)
2   //.. 1 ~ 6
3   dispatch_asyc(queue,blk7)

8个task可能根据当前系统的状态,会如下执行:

%title插图%num

Queue Create
我们可以通过GCD的API来生成Dispatch Queue

dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create(“com.example.gcd.MySerialDispatchQueue”,DISPATCH_QUEUE_SERIAL)

值得注意的是Serial Dispatch Queue的生成,当创建一个Serial Dispatch Queue,系统就默认只生成并使用一个线程。如果生成了2000个Serial Dispatch Queue那么就创建2000个线程,这对内存资源消耗是很大的。而Concurrent Dispatch Queue就没这个问题,他会根据系统状态来管理并发线程数量,所以虽然我们可以使用创建多个Serial Dispatch Queue来达到并发的目的,但是并不是GCD的初衷,我们应该使用Concurrent Dispatch Queue来处理并发任务

同样我们可以创建 Concurrent Dispatch Queue

dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create(“com.example.gcd.MyConcurrentDispatchQueue”,DISPATCH_QUEUE_CONCURRENT)

即第二个参数决定了Queue的类型是 Serial 还是 Concurrent

Queue Release
MRC
对于Dispatch Queue,Queue必须创建后由程序员自己释放,因为Dispatch Queue并没有像block那样具有作为Object-C对象来处理的技术。

dispatch_release(myConcurrentDispatchQueue)

但是,Dispatch Queue同样有引用计数管理。意味着你可以

dispatch_retain(myConcurrentDispatchQueue)

例如下面代码

dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create(“com.example.gcd.MyConcurrentDispatchQueue”,DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myConcurrentDispatchQueue, ^{
//do your task
});
dispatch_release(myConcurrentDispatchQueue);

既然dispatch_release释放掉了,为什么任务还能执行,这也是因为block对queue进行了引用,就相当于调用了dispatch_retain

ARC
对于ARC模式下,你不需要手动调用dispatch_release(myConcurrentDispatchQueue);,ARC已经允许将Dispatch Queue作为对象加入ARC内存管理。

Global Queue
我们可以获取系统为我们提供的标准Global Queue,

在iOS 7之前,系统提供了4种优先级,以调度优先级区分

名称 执行优先级
DISPATCH_QUEUE_PRIORITY_HIGH 高(*高优先)
DISPATCH_QUEUE_PRIORITY_DEFAULT 默认
DISPATCH_QUEUE_PRIORITY_LOW 低
DISPATCH_QUEUE_PRIORITY_BACKGROUND 后台
在iOS 8之后,系统提供了5种优先级,以服务质量划分的

名称 执行优先级
QOS_CLASS_USER_INTERATCTIVE 高(*高优先)
QOS_CLASS_USER_INITIATED 用户交互(不要使用耗时操作)
QOS_CLASS_DEFAULT 默认
QOS_CLASS_UTILITY 使用工具(用了做耗时操作)
QOS_CLASS_BACKGROUND 后台执行
QOS_CLASS_UNSPECIFIED 没有指定优先级
对于QOS_CLASS_UTILITY我们一般进行耗时操作,例如数据I/O,系统对其进行了优化,使得能够减少App的电量消耗。

如何设置QOS级别
dipatch_queue_attr_make_with_qos_class 或dispatch_set_target_queue方法设置队列的优先级

1 //dipatch_queue_attr_make_with_qos_class
2
3 dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_UTILITY, -1);
4
5 dispatch_queue_t queue = dispatch_queue_create(“com.starming.gcddemo.qosqueue”, attr);
6
7
8
9 //dispatch_set_target_queue
10
11 dispatch_queue_t queue = dispatch_queue_create(“com.starming.gcddemo.settargetqueue”,NULL); //需要设置优先级的queue
12
13 dispatch_queue_t referQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0); //参考优先级
14
15 dispatch_set_target_queue(queue, referQueue); //设置queue和referQueue的优先级一样

Dispatch Set Target
void dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t _Nullable queue);

dispatch_set_target_queue能够设置queue的执行阶层,无论是Concurrent Queue还是Serial Queue,一旦设置target为Serial Queue就是串行执行。

例如下列代码:

1 – (void)set_tag_test {
2     dispatch_queue_t serialQueue1 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue1”, DISPATCH_QUEUE_CONCURRENT);
3     dispatch_queue_t serialQueue2 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue2”, DISPATCH_QUEUE_CONCURRENT);
4     dispatch_queue_t serialQueue3 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue3”, DISPATCH_QUEUE_CONCURRENT);
5     dispatch_queue_t serialQueue4 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue4”, DISPATCH_QUEUE_CONCURRENT);
6     dispatch_queue_t serialQueue5 = dispatch_queue_create(“com.gcd.setTargetQueue2.serialQueue5”, DISPATCH_QUEUE_CONCURRENT);
7
8
9
10     //创建目标串行队列
11     dispatch_queue_t targetSerialQueue = dispatch_queue_create(“com.gcd.setTargetQueue2.targetSerialQueue”, NULL);
12
13     //设置执行阶层
14     dispatch_set_target_queue(serialQueue1, targetSerialQueue);
15     dispatch_set_target_queue(serialQueue2, targetSerialQueue);
16     dispatch_set_target_queue(serialQueue3, targetSerialQueue);
17     dispatch_set_target_queue(serialQueue4, targetSerialQueue);
18     dispatch_set_target_queue(serialQueue5, targetSerialQueue);
19
20     dispatch_async(serialQueue1, ^{
21         NSLog(@”%@,1″,[NSThread currentThread]);
22     });
23     dispatch_async(serialQueue1, ^{
24         NSLog(@”%@,1 2″,[NSThread currentThread]);
25     });
26     dispatch_async(serialQueue2, ^{
27         NSLog(@”%@,2″,[NSThread currentThread]);
28     });
29     dispatch_async(serialQueue3, ^{
30         NSLog(@”%@,3″,[NSThread currentThread]);
31     });
32     dispatch_async(serialQueue4, ^{
33         NSLog(@”%@,4″,[NSThread currentThread]);
34     });
35     dispatch_async(serialQueue5, ^{
36         NSLog(@”%@,5″,[NSThread currentThread]);
37     });
38     dispatch_async(targetSerialQueue, ^{
39         NSLog(@”%@,6″,[NSThread currentThread]);
40     });
41 }

输出为:

1 <NSThread: 0x60000239b580>{number = 3, name = (null)},1
2 <NSThread: 0x60000239b580>{number = 3, name = (null)},1 2
3 <NSThread: 0x60000239b580>{number = 3, name = (null)},2
4 <NSThread: 0x60000239b580>{number = 3, name = (null)},3
5 <NSThread: 0x60000239b580>{number = 3, name = (null)},4
6 <NSThread: 0x60000239b580>{number = 3, name = (null)},5
7 <NSThread: 0x60000239b580>{number = 3, name = (null)},6

dispatch_after
延迟执行

1     dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_SEC);
2     dispatch_after(time, dispatch_get_main_queue(),^{
3         //do task
4     });

dispatch_after是延迟3s加入Dispatch Queue,并不是马上执行,例如加入到主线程时,如果主线程卡段,这个延迟会大于3s

某一*对时间执行
如果dispatch_after需要在2020/04/27 11:11:11执行,那么dispatch_time_t就可以使用dispatch_walltime构造

 

1   dispatch_time_t dispatch_walltime(const struct timespec *_Nullable when, int64_t delta);

1     NSTimeInterval interval = [[NSDate date] timeIntervalSince1970];
2     struct timespec time;
3     dispatch_time_t milestone;
4     double second,subsecond;
5     subsecond = modf(interval, &second);
6     time.tv_sec = second;
7     time.tv_nsec = subsecond * NSEC_PER_SEC;
8     milestone = dispatch_walltime(&time, 0);

GCD timer
1  void
2  dispatch_source_set_timer(dispatch_source_t source, //source timer
3  dispatch_time_t start, //开始时间
4  uint64_t interval, //执行间隔
5  uint64_t leeway); //允许的延迟时间 – 系统会尽量满足,但不一定保证在延迟时间内执行

一般来说我们定时器这样写:

1     timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
2     dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, (80 * NSEC_PER_MSEC)), (80 * NSEC_PER_MSEC), 0);
3     dispatch_source_set_event_handler(timer, ^{
4         //
5     });
6     dispatch_resume(timer);

注意dispatch_source是遵循ARC的,要强引用保证其不被释放。

为什么GCD定时器相比NSTimer定时器更准?
NSTimer是CFRunLoopTimerRef的toll-free bridged的,可以直接转换,当某一次执行被延后,错过了时间点,那么NSTimer会选择不执行此次回调,等到下次执行。所以相比来说,GCD定时器更为准确。

此外 GCD定时器无法保证每次的执行同时在一个线程中,就算是Serial队列也不行,而NSTimer是加入到线程的runloop中,所以必定是同一个线程,当我们需要单线程执行时,需要注意这点。

Dispatch Group
dispatch_group_notify
我们一般用dispatch_group处理多个任务完成后,执行某个操作

1 – (void)dispatch_group_test {
2     dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
3     dispatch_group_t group = dispatch_group_create();
4     dispatch_group_async(group, queue, ^{
5         NSLog(@”blk0;”);
6     });
7     dispatch_group_async(group, queue, ^{
8         NSLog(@”blk1;”);
9     });
10     dispatch_group_async(group, queue, ^{
11         NSLog(@”blk2;”);
12     });
13
14     //1. notify
15     dispatch_group_notify(group, dispatch_get_main_queue(), ^{
16         NSLog(@”done”);
17     });
18
19     //MRC
20 //    dispatch_release(group);
21 }

控制台输出为:

1 2020-04-29 16:30:20.748658+0800 GCDTest[51629:2202347] blk0;
2 2020-04-29 16:30:20.748668+0800 GCDTest[51629:2202345] blk1;
3 2020-04-29 16:30:20.748687+0800 GCDTest[51629:2202346] blk2;
4 2020-04-29 16:30:20.761685+0800 GCDTest[51629:2201079] done

追加到Dispatch Group的block会对Dispatch Group进行dispatch_retain并持有,在block 执行完之后释放Dispatch Group,所以一旦Dispatch Group使用结束,意味着block都不保持其引用了,可以放心释放。

dispatch_group_wait
判断指定时间后,task是否执行完,使用dispatch_group_wait

将上面1部分替换为:

1
2     dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 1ull*NSEC_PER_SEC);
3     long result = dispatch_group_wait(group, time);
4
5     if (result == 0) {
6         // Group 中task全部执行完
7     }else {
8         // Group 中task还在执行中
9     }

我们可以通过将time参数设置为DISPATCH_TIME_NOW,然后在Runloop每次循环中来判断task是否执行完,以达到和dispatch_group_notify同样的效果。

我们可以通过将time参数设置为DISPATCH_TIME_FOREVER来保证任务一定执行完成。等同于dispatch_group_notify

dispatch_barrier_async
对于访问数据库文件,我们要避免数据竞争,资源是互斥的。虽然我们可以使用Serial Dispatch Queue来解决这样的问题,但是为了高效处理,写入操作确实不可与其他写入以及读取操作同时进行,但是多个读取操作时可以同时进行的,只需要保证写入是在多个读取之后进行。

1 – (void)dispatch_barrier_test {
2     dispatch_queue_t queue = dispatch_queue_create(“com.example.gcd.barrier”, DISPATCH_QUEUE_CONCURRENT);
3     dispatch_async(queue, ^{
4         NSLog(@”read 0″);
5     });
6     dispatch_async(queue, ^{
7         NSLog(@”read 1″);
8     });
9     dispatch_async(queue, ^{
10         NSLog(@”read 2″);
11     });
12     dispatch_barrier_async(queue, ^{
13         NSLog(@”write”);
14     });
15     dispatch_async(queue, ^{
16         NSLog(@”read 3″);
17     });
18     dispatch_async(queue, ^{
19         NSLog(@”read 4″);
20     });
21     dispatch_async(queue, ^{
22         NSLog(@”read 5″);
23     });
24 }

这样就可以保证多次并发read

1 2020-04-29 17:45:00.149982+0800 GCDTest[56002:2263229] read 2
2 2020-04-29 17:45:00.149982+0800 GCDTest[56002:2263230] read 0
3 2020-04-29 17:45:00.149999+0800 GCDTest[56002:2263239] read 1
4 2020-04-29 17:45:00.150130+0800 GCDTest[56002:2263239] write
5 2020-04-29 17:45:00.150215+0800 GCDTest[56002:2263239] read 3
6 2020-04-29 17:45:00.150220+0800 GCDTest[56002:2263230] read 4
7 2020-04-29 17:45:00.150234+0800 GCDTest[56002:2263229] read 5

dispatch_apply
当我们需要将一个block加入到queue中,并多次执行时,使用dispatch_apply,dispatch_apply会阻塞当前线程,并等待queue执行完成。

1 – (void)dispatch_apply_test {
2     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
3     dispatch_apply(10, queue, ^(size_t index) {
4         NSLog(@”%zu”,index);
5     });
6     NSLog(@”done”);
7 }

输出为:

1 2020-04-29 18:00:27.838731+0800 GCDTest[56107:2271775] 0
2 2020-04-29 18:00:27.838739+0800 GCDTest[56107:2271897] 1
3 2020-04-29 18:00:27.838739+0800 GCDTest[56107:2271893] 2
4 2020-04-29 18:00:27.838759+0800 GCDTest[56107:2271894] 3
5 2020-04-29 18:00:27.838858+0800 GCDTest[56107:2271897] 4
6 2020-04-29 18:00:27.838860+0800 GCDTest[56107:2271893] 5
7 2020-04-29 18:00:27.838861+0800 GCDTest[56107:2271894] 6
8 2020-04-29 18:00:27.838898+0800 GCDTest[56107:2271775] 7
9 2020-04-29 18:00:27.838941+0800 GCDTest[56107:2271897] 8
10 2020-04-29 18:00:27.838951+0800 GCDTest[56107:2271893] 9
11 2020-04-29 18:00:27.839616+0800 GCDTest[56107:2271775] done

dispatch_resume/dispatch_suspend
当多个task在Dispatch Queue中执行时,有时不想再继续执行了,可以使用dispatch_suspend将队列挂起。再使用dispatch_resume恢复,值得注意的是,并不能取消已经开始的任务。

对于想取消的线程,并能监听线程的各种状态,可以使用NSOperation和NSOperationQueue,还能够设置*大并发量。

NSOperation、NSOperationQueue 是苹果提供给我们的一套多线程解决方案。实际上 NSOperation、NSOperationQueue 是基于 GCD更高一层的封装,完全面向对象。但是比 GCD 更简单易用、代码可读性也更高。

可以添加任务依赖,方便控制执行顺序

可以设定操作执行的优先级

任务执行状态控制:isReady,isExecuting,isFinished,isCancelled

如果只是重写NSOperation的main方法,由底层控制变更任务执行及完成状态,以及任务退出
如果重写了NSOperation的start方法,自行控制任务状态
系统通过KVO的方式移除isFinished==YES的NSOperation

可以设置*大并发量
参考链接:https://www.jianshu.com/p/cbf759bdfd0f

dispatch TLS
线程TLS技术,Thread Local Storage(TLS)线程局部存储,目的很简单,将一块内存作为某个线程专有的存储,以key-value的形式进行读写,比如在非arm架构下,使用pthread提供的方法实现:

1  void* pthread_getspecific(pthread_key_t);
2  int pthread_setspecific(pthread_key_t , const void *);

GCD中也提供了相关的技术

1 #import <Foundation/Foundation.h>
2
3 static const void * const key1 = &key1;
4
5 int main(int argc, const char * argv[]) {
6     @autoreleasepool {
7         dispatch_queue_t queue1 = dispatch_queue_create(“com.ebebya.queue1”, NULL);
8         dispatch_queue_set_specific(queue1, key1, (void *)[@”ebebya” UTF8String], NULL);
9
10         dispatch_async(queue1, ^{
11             void *value = dispatch_get_specific(key1);
12             NSString *str = [[NSString alloc] initWithBytes:value length:7 encoding:4];
13             NSLog(@”%@”, str);
14         });
15     }
16     return 0;
17 }

但是是对于一个queue队列的上下文键值对,具体实现就不追究了。

滴答清单添加到 Apple Watch 表盘,不能自动更新数据变动

我把滴答清单添加到 Apple Watch 表盘上,只能*次进行数据自动更新,然后数据变动全部都要手动点进去才能更新,第三方 App 不能像自带的例如提醒事项、天气、日历一样数据变动自动反应到表盘上吗?

miyuki
    1

miyuki   1 天前 via iPhone

Things 好像也是?每天*次看都是“…”,点进去更新一下才有“Nothing to do”
eddie4607
    2

eddie4607   1 天前

我也有同样的问题。
MarlonFan
    3

MarlonFan   1 天前

我也有同样的问题。 +1
thx2u
    4

thx2u   1 天前 via iPhone

手表点好完成,手机上角标还在
leeyom
    5

leeyom   22 小时 44 分钟前

这个问题我咨询过,确实是这么回事,似乎 apple 对于表盘 app 上的软件有更新频率的限制
theolin
    6

theolin   13 小时 56 分钟前

watchOS 上的表盘组件也好,iOS14 上的小组件也好。它们的更新都不是实时的,只有系统能决定他们的更新时间和更新频率,app 自己决定不了。

 

iOS 更新至 14.4.2 后,自带输入法又抽风了,延迟好严重

下图里显示被触碰到时,其实我的手指已经是约前一秒的感觉。

RPReplay_Final1616787960

6 条回复    2021-03-27 09:27:45 +08:00
coldear
    1

coldear   5 小时 34 分钟前

每次更新都这样,过两天就好了
bclerdx
    2

bclerdx   3 小时 8 分钟前 via Android

没看出明显延迟。
xinbaqiu
    3

xinbaqiu   2 小时 47 分钟前 via iPhone   ❤️ 1

如果你是想要表示手指实际触碰跟显示触碰之间的延迟来说明新版本输入法抽风的话,这个图并不能说明?
starrystarry
    4

starrystarry   2 小时 36 分钟前

关掉 按键重复 试试
TmacV2
    5

TmacV2   2 小时 33 分钟前 via iPhone

对 ios 更新已经没有丁点兴趣了
thx2u
    6

thx2u   1 小时 22 分钟前 via iPhone

同事的 iPhone6p,一次都没更新过,如买来时流畅,且没遇到安全性问题、漏洞的网络攻击。
如果她每每更新,那么直接卡废了,变成年年换用户,更别提新功能、安不安全
友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速