C#中将字符串通过GZipStream进行压缩时的注意事项
背景, 今天在写代码时要用到GZipStream来压缩需要Web传输的数据块。原本以为GZipStream Write ->Flush ->读取对应MemoryStream数据就Okay的事情,却总是得不到正确的结果。 研究, 经过查询MSDN,原来只有在GZipStream被Dispose后,对应的MemoryStream中才会有真正的压缩数据被写入。 以下是我用来测试的代码片段(红色部分为原来的错误调用,橙色部分是正确的调用方式) string data = "<Root><PIGContent>test</PIGContent><RemoteUrl>http://www.a.com</RemoteUrl></Root>"; byte[] buffer = System.Text.UTF8Encoding.UTF8.GetBytes(data); byte[] compressedbuffer = null; //Compress buffer MemoryStream ms = new MemoryStream(); using(GZipStream zs = new GZipStream(ms, CompressionMode.Compress,true)) { zs.Write(buffer, 0, buffer.Length); //下面两句被注释掉的代码有问题, 对应的compressedbuffer的长度只有10--该10字节应该只是压缩buffer的header //zs.Flush(); //compressedbuffer = ms.ToArray(); } //只有GZipStream在Dispose后调应对应MemoryStream.ToArray()所得到的Buffer才是我们需要的结果 compressedbuffer = ms.ToArray(); 总结, 相信大家都会对GZipstream这种别扭的操作方式表示不满,微软对此也表示过歉意,但是由于其考虑到要兼容就的代码,因此即使在.Net 4.5中你还是得忍受这种不和谐的代码。 本篇小结如有不妥之处,烦请指正。 from: https://blog.csdn.net/missautumn/article/details/8351296
View DetailsJMeter入门
Jmeter简介 Jmeter的基本概念 百度百科: Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测试,但后来扩展到其他测试领域。 它可以用于测试静态和动态资源,例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库、FTP 服务器, 等等。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来自不同压力类别下测试它们的强度和分析整体性能。另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。为了最大限度的灵活性,JMeter允许使用正则表达式创建断言 我们为什么使用Jmeter 开源免费,基于Java编写,可集成到其他系统可拓展各个功能插件 支持接口测试,压力测试等多种功能,支持录制回放,入门简单 相较于自己编写框架或其他开源工具,有较为完善的UI界面,便于接口调试 多平台支持,可在Linux,Windows,Mac上运行 Jmeter安装配置 Windows下Jmeter下载安装 登录 http://jmeter.apache.org/download_jmeter.cgi ,根据自己平台,下载对应文件 安装JDK,配置环境变量(具体步骤不做介绍) 将下载Jmeter文件解压,打开/bin/jmeter.bat 其他平台安装Jmeter 与Windows平台一致,除入口文件不同,例如linux平台下为/bin/jmeter.sh Jmeter的目录结构 /bin 目录(常用文件介绍) examples:目录下包含Jmeter使用实例 ApacheJMeter.jar:JMeter源码包 jmeter.bat:windows下启动文件 jmeter.sh:Linux下启动文件 jmeter.log:Jmeter运行日志文件 jmeter.properties:Jmeter配置文件 jmeter-server.bat:windows下启动负载生成器服务文件 jmeter-server:Linux下启动负载生成器文件 /docs目录——Jmeter帮助文档 /extras目录——提供了对Ant的支持文件,可也用于持续集成 /lib目录——存放Jmeter依赖的jar包,同时安装插件也放于此目录 /licenses目录——软件许可文件,不用管 /printable_docs目录——Jmeter用户手册 Jmeter相关插件安装: 插件安装: Jmeter的插件安装很简单,只需要下载对应插件解压即可。 下载地址:http://jmeter-plugins.org/downloads/all/ 下载后解压放入:apache-jmeter-2.12\lib\ext\目录下 重启jmeter ps:数据库链接驱动如果需要需要专门下载,例如mysql需要jdbc的jar包,地址:http://dev.mysql.com/downloads/file/?id=462850 使用注意事项:添加第三方插件并使用后保存的jmx文件在未添加该插件的运行环境下会导致无法打开该文件并报错,请保持环境一致性。 用例生成与导出: Jmeter的用例格式为jmx文件,实际为xml格式,感兴趣可以学习下自己定制生成想要的jmx文件。 生成原则: 每个功能模块为一个独立的jmx文件。增加可维护性。(尽量不要将一个jmx文件放入太多功能,后期维护成本会很高。) 模块的私有变量保存在模块中,多模块共有的(例如服务器ip端口等)可以考虑存在单独的文件中读取。 接口测试不要放太多线程,毕竟不是做压力测试,意义也不大。 导出方法: 编写测试用例 文件——保存为——确定: Jmeter常用文件类型 Jmx文件 文件的实际类型:xml 文件样本: <jmeterTestPlan version="1.2" properties="1.8"> <hashTree> <TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test" enabled="true"> <elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true"> <collectionProp name="Arguments.arguments"/> </elementProp> <stringProp name="TestPlan.user_define_classpath"></stringProp> <boolProp […]
View Details获取CPU、内存、磁盘、进程信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Management; using System.Runtime.InteropServices; using System.Text; namespace ConsoleApp1 { /// /// 系统信息类 - 获取CPU、内存、磁盘、进程信息 /// public class SystemInfo { private int m_ProcessorCount = 0; //CPU个数 private PerformanceCounter pcCpuLoad; //CPU计数器 private long m_PhysicalMemory = 0; //物理内存 private const int GW_HWNDFIRST = 0; private const int GW_HWNDNEXT = 2; private const int GWL_STYLE = (-16); private const int WS_VISIBLE = 268435456; private const int WS_BORDER = 8388608; #region AIP声明 [DllImport("IpHlpApi.dll")] extern static public uint GetIfTable(byte[] pIfTable, ref uint pdwSize, bool bOrder); [DllImport("User32")] private extern static int GetWindow(int hWnd, int wCmd); [DllImport("User32")] private extern static int GetWindowLongA(int hWnd, int wIndx); [DllImport("user32.dll")] private static extern bool GetWindowText(int hWnd, StringBuilder title, int maxBufSize); [DllImport("user32", CharSet = CharSet.Auto)] private extern static int GetWindowTextLength(IntPtr hWnd); #endregion #region 构造函数 /// /// 构造函数,初始化计数器等 /// public SystemInfo() { //初始化CPU计数器 pcCpuLoad = new PerformanceCounter("Processor", "% Processor Time", "_Total"); pcCpuLoad.MachineName = "."; pcCpuLoad.NextValue(); //CPU个数 m_ProcessorCount = Environment.ProcessorCount; //获得物理内存 ManagementClass mc = new ManagementClass("Win32_ComputerSystem"); ManagementObjectCollection moc = mc.GetInstances(); foreach (ManagementObject mo in moc) { if (mo["TotalPhysicalMemory"] != null) { m_PhysicalMemory = long.Parse(mo["TotalPhysicalMemory"].ToString()); } } } #endregion #region CPU个数 /// /// 获取CPU个数 /// public int ProcessorCount { get { return m_ProcessorCount; } } #endregion #region CPU占用率 /// /// 获取CPU占用率 /// public float CpuLoad { get { return pcCpuLoad.NextValue(); } } #endregion #region 可用内存 /// /// 获取可用内存 /// public long MemoryAvailable { get { long availablebytes = 0; //ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_PerfRawData_PerfOS_Memory"); //foreach (ManagementObject mo in mos.Get()) //{ // availablebytes = long.Parse(mo["Availablebytes"].ToString()); //} ManagementClass mos = new ManagementClass("Win32_OperatingSystem"); foreach (ManagementObject mo in mos.GetInstances()) { if (mo["FreePhysicalMemory"] != null) { availablebytes = 1024 * long.Parse(mo["FreePhysicalMemory"].ToString()); } } return availablebytes; } } #endregion #region 物理内存 /// /// 获取物理内存 /// public long PhysicalMemory { get { return m_PhysicalMemory; } } #endregion #region 获得分区信息 /// /// 获取分区信息 /// public List<DiskInfo> GetLogicalDrives() { List<DiskInfo> drives = new List<DiskInfo>(); ManagementClass diskClass = new ManagementClass("Win32_LogicalDisk"); ManagementObjectCollection disks = diskClass.GetInstances(); foreach (ManagementObject disk in disks) { // DriveType.Fixed 为固定磁盘(硬盘) if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed) { drives.Add(new DiskInfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString()))); } } return drives; } /// /// 获取特定分区信息 /// /// 盘符 public List<DiskInfo> GetLogicalDrives(char DriverID) { List<DiskInfo> drives = new List<DiskInfo>(); WqlObjectQuery wmiquery = new WqlObjectQuery("SELECT * FROM Win32_LogicalDisk WHERE DeviceID = ’" + DriverID + ":’"); ManagementObjectSearcher wmifind = new ManagementObjectSearcher(wmiquery); foreach (ManagementObject disk in wmifind.Get()) { if (int.Parse(disk["DriveType"].ToString()) == (int)DriveType.Fixed) { drives.Add(new DiskInfo(disk["Name"].ToString(), long.Parse(disk["Size"].ToString()), long.Parse(disk["FreeSpace"].ToString()))); } } return drives; } #endregion #region 获得进程列表 /// /// 获得进程列表 /// public List<ProcessInfo> GetProcessInfo() { List<ProcessInfo> pInfo = new List<ProcessInfo>(); Process[] processes = Process.GetProcesses(); foreach (Process instance in processes) { try { pInfo.Add(new ProcessInfo(instance.Id, instance.ProcessName, instance.TotalProcessorTime.TotalMilliseconds, instance.WorkingSet64, instance.MainModule.FileName)); } catch { } } return pInfo; } /// /// 获得特定进程信息 /// /// 进程名称 public List<ProcessInfo> GetProcessInfo(string ProcessName) { List<ProcessInfo> pInfo = new List<ProcessInfo>(); Process[] processes = Process.GetProcessesByName(ProcessName); foreach (Process instance in processes) { try { pInfo.Add(new ProcessInfo(instance.Id, instance.ProcessName, instance.TotalProcessorTime.TotalMilliseconds, instance.WorkingSet64, instance.MainModule.FileName)); } catch { } } return pInfo; } #endregion #region 结束指定进程 /// /// 结束指定进程 /// /// 进程的 Process ID public static void EndProcess(int pid) { try { Process process = Process.GetProcessById(pid); process.Kill(); } catch { } } #endregion #region 查找所有应用程序标题 /// /// 查找所有应用程序标题 /// /// 应用程序标题范型 public static List<string> FindAllApps(int Handle) { List<string> Apps = new List<string>(); int hwCurr; hwCurr = GetWindow(Handle, GW_HWNDFIRST); while (hwCurr > 0) { int IsTask = (WS_VISIBLE | WS_BORDER); int lngStyle = GetWindowLongA(hwCurr, GWL_STYLE); bool TaskWindow = ((lngStyle & IsTask) == IsTask); if (TaskWindow) { int length = GetWindowTextLength(new IntPtr(hwCurr)); StringBuilder sb = new StringBuilder(2 * length + 1); GetWindowText(hwCurr, sb, sb.Capacity); string strTitle = sb.ToString(); if (!string.IsNullOrEmpty(strTitle)) { Apps.Add(strTitle); } } hwCurr = GetWindow(hwCurr, GW_HWNDNEXT); } return Apps; } #endregion } public class DiskInfo { public DiskInfo() { } public DiskInfo(string name, long size, long freeSpace) { this.Name = name; this.Size = size; this.FreeSpace = freeSpace; } public string Name { get; set; } public long Size { get; set; } public long FreeSpace { get; set; } } public class ProcessInfo { public ProcessInfo() { } public ProcessInfo(int id, string processName, double totalMilliseconds, long workingSet64, string fileName) { Id = id; ProcessName = processName; TotalMilliseconds = totalMilliseconds; WorkingSet64 = workingSet64; FileName = fileName; } public int Id { get; set; } public string ProcessName { get; set; } public double TotalMilliseconds { get; set; } public long WorkingSet64 { get; set; } public string FileName { get; set; } } } |
参考: https://www.cnblogs.com/zery/p/6256850.html https://www.cnblogs.com/maowang1991/archive/2013/08/27/3285983.html
View DetailsC#读取Windows日志
管理-->事件查看器 可以查看【应用程序】、【安全】、【系统】等分类的日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
static void Main(string[] args) { EventLog eventlog = new EventLog(); eventlog.Log = "Security"; //"Application"应用程序, "Security"安全, "System"系统 EventLogEntryCollection eventLogEntryCollection = eventlog.Entries; foreach (EventLogEntry entry in eventLogEntryCollection) { //if (entry.EventID == 4624) //{ // continue; //} string info = string.Empty; if (@"TaskScheduler" == entry.Source.ToString()) { info += "类型:" + entry.EntryType.ToString() + ";"; info += "日期" + entry.TimeGenerated.ToLongDateString() + ";"; info += "时间" + entry.TimeGenerated.ToLongTimeString() + ";"; info += "来源" + entry.Source.ToString() + ";"; Console.WriteLine(info); } } } |
from:https://www.cnblogs.com/gossip/p/5249982.html
View DetailsWeb获取服务器信息以及监控服务器
准备工作: Hyperic-hq官方网站:http://www.hyperic.com Sigar.jar下载地址:http://sourceforge.net/projects/sigar/files/ Sigar.jar文档地址:https://support.hyperic.com/display/SIGAR/Home 介绍 Sigar全名是System Information Gatherer And Reporter,中文名是系统信息收集和报表工具。我是一个开源的工具,提供了跨平台的系统信息收集的API ,是Hyperic-hq产品的基础包,是Hyperic HQ主要的数据收集组件。它用来从许多平台收集系统和处理信息。 这些平台包括:Linux,Windows,Solaris,AIX,HP-UX,FreeBSD和Mac OSX。 可以收集的信息 CPU信息:包括基本信息(vendor、model、mhz、cacheSize)和统计信息(user、sys、idle、nice、wait) 文件系统信息:包括Filesystem、Size、Used、Avail、Use%、Type 事件信息:类似Service Control Manager 内存信息:物理内存和交换内存的总数、使用数、剩余数;RAM的大小 网络信息:包括网络接口信息和网络路由信息 进程信息:包括每个进程的内存、CPU占用数、状态、参数、句柄 IO信息:包括IO的状态,读写大小等 服务状态信息 系统信息:包括操作系统版本,系统资源限制情况,系统运行时间以及负载,JAVA的版本信息等 使用 Sigar有C,C#,Java和Perl API,java版的API为sigar.jar。sigar.jar的底层是用C语言编写的,它通过本地方法来调用操作系统API来获取系统相关数据。 Windows操作系统下Sigar.jar 依赖sigar-amd64-winnt.dll或sigar-x86-winnt.dll linux 操作系统下则依赖libsigar-amd64-linux.so或libsigar-x86-linux.so。 具体的对应关系如下: File Language Description Required sigar.jar Java Java API Yes log4j.jar Java Java logging API No libsigar-x86-linux.so C Linux AMD/Intel 32-bit * libsigar-amd64-linux.so C Linux AMD/Intel 64-bit * libsigar-ppc-linux.so C Linux PowerPC 32-bit * libsigar-ppc64-linux.so C Linux PowerPC 64-bit * libsigar-ia64-linux.so C Linux Itanium 64-bit * libsigar-s390x-linux.so C Linux zSeries 64-bit * sigar-x86-winnt.dll C Windows AMD/Intel 32-bit * sigar-amd64-winnt.dll C Windows AMD/Intel 64-bit * libsigar-ppc-aix-5.so C AIX PowerPC 32-bit * libsigar-ppc64-aix-5.so C […]
View Detailsphp-fpm配置优化
前言: 1.少安装PHP模块, 费内存 2.调高linux内核打开文件数量,可以使用这些命令(必须是root帐号)(我是修改/etc/rc.local,加入ulimit -SHn 51200的)
1 2 3 |
echo `ulimit -HSn 65536` >> /etc/profile echo `ulimit -HSn 65536` >> /etc/rc.local source /etc/profile |
如果ulimit -n数量依旧不多(即上面配置没生效)的话, 可以在 /etc/security/limits.conf 文件最后加上
1 2 |
* soft nofile 51200 * hard nofile 51200 |
1.与Nginx使用Unix域Socket通信(Nginx和php-fpm在同一台服务器) Unix域Socket因为不走网络,的确可以提高Nginx和php-fpm通信的性能,但在高并发时会不稳定。 Nginx会频繁报错:connect() to unix:/dev/shm/php-fcgi.sock failed (11: Resource temporarily unavailable) while connecting to upstream 可以通过下面两种方式提高稳定性: 1)调高nginx和php-fpm中的backlog 配置方法为:在nginx配置文件中这个域名的server下,在listen 80后面添加default backlog=1024。 同时配置php-fpm.conf中的listen.backlog为1024,默认为128。 2)增加sock文件和php-fpm实例数 再新建一个sock文件,在Nginx中通过upstream模块将请求负载均衡到两个sock文件背后的两套php-fpm实例上。 2.php-fpm参数调优 pm = dynamic; 表示使用哪种进程数量管理方式 dynamic表示php-fpm进程数是动态的,最开始是pm.start_servers指定的数量,如果请求较多,则会自动增加,保证空闲的进程数不小于pm.min_spare_servers,如果进程数较多,也会进行相应清理,保证多余的进程数不多于pm.max_spare_servers static表示php-fpm进程数是静态的, 进程数自始至终都是pm.max_children指定的数量,不再增加或减少 pm.max_children = 300; 静态方式下开启的php-fpm进程数量 pm.start_servers = 20; 动态方式下的起始php-fpm进程数量 pm.min_spare_servers = 5; 动态方式下的最小php-fpm进程数量 pm.max_spare_servers = 35; 动态方式下的最大php-fpm进程数量 如果pm为static, 那么其实只有pm.max_children这个参数生效。系统会开启设置数量的php-fpm进程 如果pm为dynamic, 那么pm.max_children参数失效,后面3个参数生效。系统会在php-fpm运行开始的时候启动pm.start_servers个php-fpm进程,然后根据系统的需求动态在pm.min_spare_servers和pm.max_spare_servers之间调整php-fpm进程数 那么,对于我们的服务器,选择哪种pm方式比较好呢?事实上,跟Apache一样,运行的PHP程序在执行完成后,或多或少会有内存泄露的问题。这也是为什么开始的时候一个php-fpm进程只占用3M左右内存,运行一段时间后就会上升到20-30M的原因了。 对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效率。因为频繁开关php-fpm进程也会有时滞,所以内存够大的情况下开静态效果会更好。数量也可以根据 内存/30M 得到,比如8GB内存可以设置为100,那么php-fpm耗费的内存就能控制在 2G-3G的样子。如果内存稍微小点,比如1G,那么指定静态的进程数量更加有利于服务器的稳定。这样可以保证php-fpm只获取够用的内存,将不多的内存分配给其他应用去使用,会使系统的运行更加畅通。 对于小内存的服务器来说,比如256M内存的VPS,即使按照一个20M的内存量来算,10个php-cgi进程就将耗掉200M内存,那系统的崩溃就应该很正常了。因此应该尽量地控制php-fpm进程的数量,大体明确其他应用占用的内存后,给它指定一个静态的小数量,会让系统更加平稳一些。或者使用动态方式,因为动态方式会结束掉多余的进程,可以回收释放一些内存,所以推荐在内存较少的服务器或VPS上使用。具体最大数量根据 内存/20M 得到。比如说512M的VPS,建议pm.max_spare_servers设置为20。至于pm.min_spare_servers,则建议根据服务器的负载情况来设置,比较合适的值在5~10之间。 在4G内存的服务器上200就可以(我的1G测试机,开64个是最好的,建议使用压力测试获取最佳值) pm.max_requests = 10240; nginx php-fpm配置过程中最大问题是内泄漏出问题:服务器的负载不大,但是内存占用迅速增加,很快吃掉内存接着开始吃交换分区,系统很快挂掉!其实根据官方的介绍,php-cgi不存在内存泄漏,每个请求完成后php-cgi会回收内存,但是不会释放给操作系统,这样就会导致大量内存被php-cgi占用。 官方的解决办法是降低PHP_FCGI_MAX_REQUESTS的值,如果用的是php-fpm,对应的php-fpm.conf中的就是max_requests,该值的意思是发送多少个请求后会重启该线程,我们需要适当降低这个值,用以让php-fpm自动的释放内存,不是大部分网上说的51200等等,实际上还有另一个跟它有关联的值max_children,这个是每次php-fpm会建立多少个进程,这样实际上的内存消耗是max_children*max_requests*每个请求使用内存,根据这个我们可以预估一下内存的使用情况,就不用再写脚本去kill了。 request_terminate_timeout = 30; 最大执行时间, 在php.ini中也可以进行配置(max_execution_time) request_slowlog_timeout = 2; 开启慢日志 slowlog = log/$pool.log.slow; 慢日志路径 rlimit_files = 1024; 增加php-fpm打开文件描述符的限制 3.php-fpm的高CPU使用率排查方法 1)使用top命令, 直接执行top命令后,输入1就可以看到各个核心的CPU使用率。而且通过top […]
View Details福布斯:为什么你应该关注谷歌的 Flutter 和 Fuchsia?
就像麦圭尔在电影《毕业生》(The Graduate) 中对年轻的本杰明脱口而出的 “plastics” 一样,我们一直在寻找下一个会引发震动的重大事件。过去10年一直由手机主导,下一个十年则将是物联网(IoT)设备。 Flutter 和 Fuchsia ,这两个简单的词汇将成为推动手机和物联网下一代革命的燃料。它们是可以让这些设备改变你的日常生活的技术,并且每年都会为大小企业带来数十亿美元的收入。 作为一名拥有30多年经验的软件开发人员和福布斯纽约商业委员会的成员,我经常被公司问答两个基本问题。一是“我们应该成立自己的 IT 部门,还是在海外或外包开发”,二是“我应该选择什么样的开发语言,以及下一个新兴技术是什么”?嗯,答案就是 Flutter 和 Fuchsia 。预计2019年,你会在任何地方看到这两个词,现在你有机会抢跑。 Flutter 是谷歌全新的开发平台,允许开发者用一种简单的语言为苹果的 iPhone / iPad iOS 平台和谷歌的 Android 手机/平板电脑编写应用。此前已有多次其他类似的尝试并取得一定的成功,但谷歌最终用 Flutter 解决了移动开发难题。它是开源和免费的,非常适合预算有限的学生和其他开发者。我的建议是立即下载并使用它,这将是你对自己或公司的最佳投资。 接下来是 Fuchsia ,基于谷歌在 Android 和 Chrome 操作系统上的经验,他们踏上了这条构建新系统的旅程。操作系统是你日常使用的设备的核心,像是用于移动设备的 iOS ,用于电脑的 OSX ,微软的 Windows 和谷歌的 Android 和 Chrome OS 。为什么还有公司想在如今的环境中再创建一个全新的操作系统?答案很简单:物联网。有数以千计的物联网设备开始融入我们的日常生活:亚马逊的 Alexa ,特斯拉的自动驾驶汽车,智能温度控制设备,甚至是家用智能锁。 Fuchsia 基于 microkernel 微内核,小巧但功能强大。它最初由 Android 和 ChromeOS 所依赖的 Linux 提供支持,但谷歌现在正抛弃 Linux 并创建了一个能够在通用设备上运行的微内核操作系统 —— 从嵌入式和物联网设备到智能手机、平板电脑和个人电脑。我相信他们的计划是在未来五年内在数十亿的物联网设备中安装 Fuchsia 。秘密武器是 Fuchsia 的用户界面和应用程序,都是用 Flutter 编写的。Flutter 不仅可以简化应用开发,而且被用于开发移动和物联网设备的未来系统。 至于海外开发或外包开发有很多原因,像是提高效率、节省时间和降低成本。在过去10年中,公司选择外包最重要原因是内部缺乏移动应用开发技能。为 iOS 和 Android 训练原生移动开发人才通常需要两年时间和 10 万美元的薪水和教育投入,很少有公司愿意进行这种投资。但是,海外或外包团队也存在巨大风险。事实证明,质量上的妥协,沟通时间和额外的差旅成本,会抵销大多份的效益。 Flutter 将极大地改善未来几年内部开发和初创公司的前景。 Flutter 很容易学习,你甚至可以在没有编码经验的情况下自学。对于新手程序员来说,可能存在学习曲线,但任何有一点经验的人都会在两个月内上手,而不是两年。这就是我为什么说现在开始学习是企业和创业公司真正的机会。Flutter 在学习和使用上的便利性,将让你有机会在快节奏的技术领域中走在前列。 from:https://www.oschina.net/news/98480/why-should-looking-at-flutter-and-fuchsia
View DetailsFlutter
Flutter 是一种新型的方式,用于创建高性能、跨平台的移动应用。由 Google 的工程师团队打造。Flutter 针对当下以及未来的移动设备进行优化,专注于 Android and iOS 低延迟的输入和高帧率。 Flutter 可以给开发者提供简单、高效的方式来构建和部署跨平台、高性能移动应用;给用户提供漂亮、快速、jitter-free 的 app 体验。 Flutter 的主要组件: 一个高度优化, mobile-first 2D 渲染引擎 (保护对 text 优秀的支持 ) 一个 functional-reactive 框架 (可选的,你也可以引入你自己的框架) 一组 Material Design 部件 (可选的,你也可以引入你自己的部件)库 ,工具,和一个用于 Atom 的插件。 一个开源的 Flutter 应用实例:FlutterOSC from:https://www.oschina.net/p/flutter
View DetailsWindws Server 2012 Server Backup详解
一、Windows Server Backup介绍 Windows Server Backup是系统自带的备份和恢复组件,和Windows Server 2003中的NTbackup类似。相对于其他第三方备份软件,Windows Server Backup由于是系统自带组件,不需要额外购买授权,从而减少IT开支。注意:Windows Server Backup不支持备份到磁带。 Windows Server Backup可以备份一个完整的服务器(所有卷),所选卷,系统状态,或特定的文件或文件夹,并创建一个备份,您可以使用裸机恢复。您可以恢复卷,文件夹,文件,某些应用程序和系统状态。而且,硬盘故障等灾害的情况下,您可以执行裸机恢复。 Windows Server 2012 中 Windows Server Backup功能更新: 1.从Hyper-V主机备份和恢复单个虚拟机 2.备份版本功能改进 3.支持大于2TB的卷备份和4K扇区支持 4.支持备份群集共享卷(CSV) 二、Windows Server Backup安装。 1.实验环境 2.在Labsvr02中,打开服务器管理器,点击“添加角色和功能”。 3.在向导中,连续点4次“下一步”,在功能页面勾选“Windows Server Backup”,然后点“下一步”进行安装即可完成安装。 三、文件的备份 一次性备份 1.打开Windows Server Backup,右击“本地备份”后选择“一次性备份”。在打开的向导中直接"下一步".由于是一次性的备份,所以计划的备份时不可选的。 2.我们只需对特定的文件进行备份,选择“自定义”。如果选择整个服务器,将备份所有服务器数据。 3.点击“添加项目”,选择需要备份的文件。点击“高级设置”还可以添加排除,排除一些无需备份的文件类型,如:mp3和视频文件等。 4.选择备份文件存放路径。可以选择本地存储或远程共享文件夹,不支持磁带驱动器。 需要注意: 本地驱动器:必须是NTFS格式的驱动器,不能将备份存储在USB闪存驱动器。容量至少是备份文件大小的1.5倍,才能存储几个备份版本。 远程共享文件夹:每次创建新的备份时都将覆盖旧的备份,如果需要存储多备份版本的话,请不要选择此项。同时,在已包含备份的共享文件夹创建备份时,如果备份过程失败,则可能会丢失所有备份。 5.选择备份存储目标。注意:无法选择需要备份文件所在的分区,强烈建议生产环境不要选择系统盘作为备份目标。由于实验机器上只有C、D两个分区,所以只能选C盘。 6.备份完成好可以在备份目标看到相应的备份文件。 备份计划(自动备份) 1.在Windows Server Backup控制台,右击“本地备份”,选择“备份计划”。 2.选择需要备份的文件。 3.点击“添加项目”,选择需要备份的文件。点击“高级设置”还可以添加排除,排除一些无需备份的文件类型,如:mp3和视频文件等。 4.根据需求选择备份开始时间及备份频率。 5.参考各个选项的说明,根据企业环境选择相应的存储。这里作为演示选择“备份到卷”(生产环境,请慎重选择此项,卷的性能会降低) 6.添加相应的分区作为目标卷。 8.如需修改备份计划选择右侧的“备份计划”,则可以在向导中修改或停止该计划备份。 9.如需在计划时间之外,进行手动备份,则再次在控制台右侧选择“一次性备份”,然后选择“计划备份选项”。 1、打开任务计划,在任务计划程序(本地)-任务计划程序库 –Microsoft-Windows-Backup中可以看到设置的备份计划。 2、右键备份任务计划,选“属性”—触发器—选“编辑”,可以在编辑触发器界面,更改备份周期,现更改为每周,星期日21:00:00开始备份。 四、还原文件 1.为了演示还原是否成功,将部分文件删除。 2.在控制台右侧,选择“恢复”。 3.由于前面备份的文件就存储在本地磁盘,所以选择的“此服务器”。 4.选择需要恢复哪天的备份,然后选择需要恢复的类型。 5.选择要还原的文件,无法选择单个文件,只能选择目录。作为演示选择备份的跟目录,还原所有文件。 6.选择恢复到目标位置,如果选择其他位置,输入对应路径即可。有相同文件时是否需要覆盖以及是否需要连权限一起恢复。 7.确认恢复项目,点击“恢复”。 8.回到恢复目录,可以看到前面删除的文件已经成功恢复。 总结:Windows Server Backup 虽然在功能上可能和一些第三方备份软件有差距,但还是能够满意企业的基本备份需求,也可以减少IT费用的投入。Windows Server Backup 只支持完整备份和增量备份,不支持差异备份。 四、备份和还原操作系统 系统备份 1.打开Windows Server Backup,右击“本地备份”,作为演示,选择“一次性备份”。 2.选择“裸机恢复”,将备份系统状态、系统保留和系统分区。 3.由于后面需要演示这台服务器由于故障,用系统备份进行还原。选择远程共享文件夹。 4.输入在Labsvr03上创建的共享UNC路径:\\labsvr03\backup(需要确保能够访问并对该文件夹有写入权限,否则会备份失败)。是否继承该共享文件夹的权限,如果选择“不继承”则需要输入相应的用户凭据。最后点“备份”,等待备份完成。 系统还原 1.为了演示,现假设Labsvr02这台服务器由于故障,无法启动,进行裸机恢复。在该服务器上插入Windows Server […]
View Details