Jenkins file一行代码部署.NET程序到K8S

Jenkins file一行代码部署.NET程序

2cb0066fa2d19cea8928620a9ac25fc0.png


什么是Jenkins共享库

随着微服务的增多,每个项目的都需要pipline文件,这样的话Pipeline代码冗余度高,并且pipeline的功能越来越复杂。

jenkins可以使用Shared Lib,将一些公共的pipeline抽象做成模块代码,在各种项目pipeline之间复用,以减少冗余。

共享库目录结构

共享库根目录
|-- vars|-- test1.groovy
|-- src|-- test2.groovy
|-- resources

vars: 依赖于Jenkins运行环境的Groovy脚本。其中的Groovy脚本被称之为全局变量
src: 标准的Java源码目录结构,其中的Groovy脚本被称为类库(Library class)。
resources: 目录允许从外部库中使用 libraryResource 步骤来加载有关的非 Groovy 文件。

引用共享库的方式

#!/usr/bin/env groovy// 引用默认配置的共享库
@Library('demo-shared-library') _// 引用指定分支、tag的共享库代码
@Library('demo-shared-library@1.0') _// 引用多个指定分支tag的共享库
@Library('demo-shared-library@$Branch/Tag','demo-shared-library-test@$Branch/Tag') _@Library('utils') import org.foo.Utilities@Library('utils') import static org.foo.Utilities.*

vars下的全局变量

/vars下的全局变量必须以全小写或驼峰(camelCased)
/vars/*.groovy若实现call()方法,直接引用时默认执行其中的方法

实现一行代码部署.NET程序到K8S

安装Jenkins Master

# master
docker run --name jenkins-blueocean -u root --privileged -d -p 8080:8080 -p 50000:50000 -v D:/architecture/jenkins/data:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock jenkinsci/blueocean # 访问:http://ip:8080/
# jenkins密码,查看容器日志: 7285ced325a24483bfdaab227415fdac
# 安装推荐插件

安装Jenkins Agent

Manage Jenkins -> Manage Nodes and Clouds -> New Node

  • Name: agent2/agent3

  • Labels: agentnode

  • Launch method: Launch agent by connecting it to the master

Build Agent Docker Image

# slave
# Dockerfile
FROM jenkins/inbound-agent:latest
USER rootRUN apt-get update
RUN apt-get -y install ca-certificates curl gnupg lsb-release
RUN curl -fsSL https://get.docker.com -o get-docker.sh
RUN sh get-docker.shRUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
RUN install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
RUN kubectl version --clientENV JMETER_VERSION=5.4.1
ENV JMETER_HOME=/jmeter/apache-jmeter-${JMETER_VERSION}
ENV JMETER_PATH=${JMETER_HOME}/bin:${PATH}
ENV PATH=${JMETER_HOME}/bin:${PATH}RUN mkdir /jmeter
COPY apache-jmeter-${JMETER_VERSION}.tgz /jmeter
RUN cd /jmeter && tar xvf apache-jmeter-${JMETER_VERSION}.tgz #其中tgz文件请去官网下载
RUN sed -i 's/#jmeter.save.saveservice.output_format=csv/jmeter.save.saveservice.output_format=xml/g'  /jmeter/apache-jmeter-5.4.1/bin/jmeter.propertiesdocker build -t chesterjenkinsagent .
docker tag chesterjenkinsagent:latest 192.168.43.95/jenkins/chesterjenkinsagent:v1
docker login --username=admin --password=123456  192.168.43.95
docker push 192.168.43.95/jenkins/chesterjenkinsagent:v1

运行Agent,其中的密钥通过jenkins的agent信息获取

5f885bf578559f0936c89f21a3a19356.png

# agent4
docker run  -v /var/run/docker.sock:/var/run/docker.sock --name agent4  -d --init 192.168.43.95/jenkins/chesterjenkinsagent:v1 -url http://192.168.43.94:8080   1e84c896dbffc0c325587eedb6301ab0ae66d3f4b49c4628dbb05714e382d7a2 agent4

新增K8S凭据

  • 将k8s集群的配置文件导出 ~/.kube/config

  •  Mange Jenkins -> Manage Credentials -> Add Credentials -> Secret File

  • 选择导出的kubeconfig,设置id为kubeconfig

新增Harbor凭据

  • Mange Jenkins -> Manage Credentials -> Add Credentials -> Username with password

  • 输入Harbor的用户名密码

新增Gitee凭据

  • Mange Jenkins -> Manage Credentials -> Add Credentials -> Username with password

  • 输入Gitee的用户名密码

安装插件

Manage Jenkins -> Manage Plugins -> Search "Performance" -> install

管理共享库

Manage Jenkins -> Configure System -> Global Pipeline Libraries,其中的git地址是共享库的地址

1a84e82ff3dd196fc7942a5d282f1f98.png

共享库中新增以下代码

vars/run.groovy

#!/usr/bin/env groovydef call(String nameSpaceName, String serviceName, String servicePath, String servicePort, String nodePort, Map envInfo) {def devBranch = envInfo['dev']def prodBranch = envInfo['prod']pipeline {agent {label 'agentnode'}environment {DEV_MY_KUBECONFIG = credentials('kubeconfig')PROD_MY_KUBECONFIG = credentials('kubeconfig')HARBOR = credentials('harbor')}stages {stage('Dev - GitPull') {steps {deleteDir()gitCheckOut devBranch, env.GIT_URL}post {success {script {echo 'pull done'}}}}stage('Dev - DockerBuild') {steps {dockerImageBuild serviceName, "${servicePath}Dockerfile"}}stage('Dev - DockerTag') {steps {dockerTag serviceName, 'dev'}}stage('Dev - DockerLogin') {steps {dockerLogin 'dev'}}stage('Dev - DockerPush') {steps {dockerPush serviceName, 'dev'}}stage('Dev - GenerateHarborSecretYAML') {steps {harborSecret nameSpaceName, serviceName, 'dev'}}stage('Dev - GenerateK8SYAML') {steps {k8sGenerateYaml nameSpaceName, serviceName, servicePath, 'dev', servicePort, nodePort}}stage('Dev - DeployToK8S') {steps {k8sDeploy servicePath, 'dev'}}stage('Dev - CheckDeployStatus') {steps {k8sCheckDeployStatus nameSpaceName, serviceName, 'dev'}}stage('Dev - Jmeter Test') {steps {jmeterTest servicePath}}stage('DeployToProd?') {steps {input '部署生产?'}}stage('Prod - GitPull') {steps {gitCheckOut prodBranch, env.GIT_URL}}stage('Prod - DockerBuild') {steps {dockerImageBuild serviceName, "${servicePath}Dockerfile"}}stage('Prod - DockerTag') {steps {dockerTag serviceName, 'prod'}}stage('Prod - DockerLogin') {steps {dockerLogin 'prod'}}stage('Prod - DockerPush') {steps {dockerPush serviceName, 'prod'}}stage('Prod - GenerateHarborSecretYAML') {steps {harborSecret nameSpaceName, serviceName, 'prod'}}stage('Prod - GenerateK8SYAML') {steps {k8sGenerateYaml nameSpaceName, serviceName, servicePath, 'prod', servicePort, nodePort}}stage('Prod - DeployToK8S') {steps {k8sDeploy servicePath, 'prod'}}stage('Prod - CheckDeployStatus') {steps {k8sCheckDeployStatus nameSpaceName, serviceName, 'prod'}}}}
}

vars/dockerImageBuild.groovy

#!/usr/bin/env groovydef call(String serviceName, String dockerfilePath) {echo "serviceName:${serviceName} dockerfilePath:${dockerfilePath}"sh "docker build -t ${serviceName} -f  ${dockerfilePath} ."
}

vars/dockerLogin.groovy

#!/usr/bin/env groovydef call(String envName) {sh 'docker login --username=$HARBOR_USR --password=$HARBOR_PSW  192.168.43.95'
}

vars/dockerPush.groovy

#!/usr/bin/env groovydef call(String serviceName,String envName) {sh "docker push 192.168.43.95/dapr/${serviceName}:${envName}-${BUILD_NUMBER}"
}

vars/dockerTag.groovy

#!/usr/bin/env groovydef call(String serviceName, String envName) {sh "docker tag ${serviceName}:latest 192.168.43.95/dapr/${serviceName}:${envName}-${BUILD_NUMBER}"
}

vars/gitCheckOut.groovy

#!/usr/bin/env groovydef call(String branchName, String gitUrl) {echo "branchName:${branchName} gitUrl:${gitUrl}"checkout([$class: 'GitSCM', branches: [[name: branchName]], extensions: [], userRemoteConfigs: [[credentialsId: 'gitee', url: gitUrl]]])
}

vars/harborSecret.groovy

def call(String namespaceName, String serviceName, String envName) {dir('harborsecret') {checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'gitee', url: 'https://gitee.com/chesterdotchen/jenkins-demo-secrets.git']]])sh """sed -i 's/{{ServiceName}}/${serviceName}/g'  secrets.yaml"""sh """sed -i 's/{{NameSpaceName}}/${namespaceName}/g'  secrets.yaml"""if (envName == 'dev') {sh("kubectl --kubeconfig  ${DEV_MY_KUBECONFIG} apply -f secrets.yaml")}if (envName == 'prod') {sh("kubectl --kubeconfig  ${PROD_MY_KUBECONFIG} apply -f secrets.yaml")}}
}

vars/jmeterTest.groovy

#!/usr/bin/env groovydef call(String servicePath) {sh "jmeter -j jmeter.save.saveservice.output_format=xml -n -t ${servicePath}jmeter.jmx -l ${servicePath}jmeter.report.jtl"sh "cp ${servicePath}jmeter.report.jtl ${servicePath}jmeter.report.${BUILD_NUMBER}.jtl"perfReport errorFailedThreshold:5, sourceDataFiles:"${servicePath}jmeter.report.jtl"sh "cat ${servicePath}jmeter.report.${BUILD_NUMBER}.jtl"sh """#!/bin/shgrep '<failure>true</failure>' ${servicePath}jmeter.report.${BUILD_NUMBER}.jtlif [ \$? = 0 ]thenexit 1elseexit 0fi"""
}

vars/k8sCheckDeployStatus.groovy

#!/usr/bin/env groovydef call(String nameSpaceName, String serviceName, String envName) {if (envName == 'dev') {sh("""ATTEMPTS=0ROLLOUT_STATUS_CMD='kubectl --kubeconfig  ${DEV_MY_KUBECONFIG} rollout status deployment/${serviceName}  -n ${nameSpaceName}-ns'until \$ROLLOUT_STATUS_CMD || [ \$ATTEMPTS -eq 60 ]; do\$ROLLOUT_STATUS_CMDATTEMPTS=\$((attempts + 1))sleep 10done""")}if (envName == 'prod') {sh("""ATTEMPTS=0ROLLOUT_STATUS_CMD='kubectl --kubeconfig  ${PROD_MY_KUBECONFIG} rollout status deployment/${serviceName}  -n ${nameSpaceName}-ns'until \$ROLLOUT_STATUS_CMD || [ \$ATTEMPTS -eq 60 ]; do\$ROLLOUT_STATUS_CMDATTEMPTS=\$((attempts + 1))sleep 10done""")}
}

vars/k8sDeploy.groovy

#!/usr/bin/env groovydef call(String servicePath, String envName) {if (envName == 'dev') {sh("kubectl --kubeconfig  ${DEV_MY_KUBECONFIG} apply -f ${servicePath}deployment.yaml")}if (envName == 'prod') {sh("kubectl --kubeconfig  ${PROD_MY_KUBECONFIG} apply -f ${servicePath}deployment.yaml")}
}

vars/k8sGenerateYaml.groovy

#!/usr/bin/env groovydef call(String namespaceName, String serviceName, String servicePath, String envName, String servicePort, String nodePort) {sh """sed "s/{{tagversion}}/${envName}-${BUILD_NUMBER}/g"  ${servicePath}deployment.yaml.tpl > ${servicePath}deployment.yaml """sh """sed -i 's/{{ServiceName}}/${serviceName}/g'  ${servicePath}deployment.yaml"""sh """sed -i 's/{{ServicePort}}/${servicePort}/g'  ${servicePath}deployment.yaml"""sh """sed -i 's/{{NodePort}}/${nodePort}/g'  ${servicePath}deployment.yaml"""sh """sed -i 's/{{NameSpaceName}}/${namespaceName}/g'  ${servicePath}deployment.yaml"""
}

jenkins-demo-secrets中代码如下

apiVersion: v1
kind: Namespace
metadata:name: {{NameSpaceName}}-ns---
apiVersion: v1
kind: Secret
metadata:name: harbor-keynamespace: {{NameSpaceName}}-ns
type: kubernetes.io/dockerconfigjson
data:.dockerconfigjson: ewoJImF1dGhzIjogewoJCSIxOTIuMTY4LjQzLjk1IjogewoJCQkiYXV0aCI6ICJZV1J0YVc0Nk1USXpORFUyIgoJCX0sCgkJInJlZ2lzdHJ5LmNuLWJlaWppbmcuYWxpeXVuY3MuY29tIjogewoJCQkiYXV0aCI6ICI2Wm1JNUxpQTU0dXVPbU5vWlc1NWFYTm9hVEV5TXc9PSIKCQl9Cgl9Cn0=

dockerconfigjson可通过以下方式获取

docker login --username=admin --password=123456 192.168.43.95
cat ~/.docker/config.json | base64

Jenkinsfile中引用共享库

项目库中需要提前编写好Dockerfile,Jenkinsfile,deployment.yaml.tpl,jmeter.jmx

768dfb746e5bc344251525e49a68d125.png

Dockerfile

#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
WORKDIR /app
EXPOSE 5001FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /src
COPY ["FrontEnd/FrontEnd.csproj", "FrontEnd/"]
COPY ["Common/Common.csproj", "Common/"]
RUN dotnet restore "FrontEnd/FrontEnd.csproj"
COPY . .
WORKDIR "/src/FrontEnd"
RUN dotnet build "FrontEnd.csproj" -c Release -o /app/buildFROM build AS publish
RUN dotnet publish "FrontEnd.csproj" -c Release -o /app/publishFROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "FrontEnd.dll"]

Jenkinsfile

#!/usr/bin/env groovy@Library('share@master') _run 'daprtest', 'frontend', './FrontEnd/', '5001', '31111', ['dev':'*/master', 'prod':'*/master']

deployment.yaml.tpl

apiVersion: v1
kind: Namespace
metadata:name: {{NameSpaceName}}-ns---
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:name: statestorenamespace: {{NameSpaceName}}-ns
spec:type: state.redisversion: v1metadata:- name: redisHostvalue: 192.168.43.102:6379- name: redisPasswordvalue: "123456"- name: actorStateStorevalue: "true"---
apiVersion: apps/v1
kind: Deployment
metadata:name: {{ServiceName}}namespace: {{NameSpaceName}}-nslabels:app: {{ServiceName}}
spec:replicas: 1selector:matchLabels:app: {{ServiceName}}template:metadata:namespace: {{NameSpaceName}}-nslabels:app: {{ServiceName}}annotations:dapr.io/enabled: "true"dapr.io/app-id: "{{ServiceName}}"dapr.io/app-port: "{{ServicePort}}"spec:imagePullSecrets:- name: harbor-keycontainers:- name: {{ServiceName}}image: 192.168.43.95/dapr/{{ServiceName}}:{{tagversion}}ports:- containerPort: {{ServicePort}}imagePullPolicy: Always---
apiVersion: v1
kind: Service
metadata:namespace: {{NameSpaceName}}-nsname: {{ServiceName}}-svc
spec:type: NodePortselector:app: {{ServiceName}}ports:- port: {{ServicePort}}targetPort: {{ServicePort}}nodePort: {{NodePort}}

jmter.jmx则根据需要自行编写

56643c704cd3e75c80ed1af1181d0181.png

新建pipline

其中的URL指向自己项目的git地址

3bc05eb7b4cec34fe0cafd4a84b1d5c0.png

构建pipline

7a13d4635865880ac028c951c12291c3.png

至此,我们已经完成了Jenkinsfile中一行代码部署我们的项目,如果有新的service,在编写好Dockerfile,deployment.yaml.tpl(保持一致),jmeter.jmx的前提下,我们只需要Jenkinsfile中通过共享库引用run方法即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/295896.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

吵架后女生和男生的夜晚!所有男生都这样吗?

1 猫&#xff1a;哪个瓜娃子开的灯&#xff1f;&#xff01;2 神回复在哪里3 舔舔舔舔舔&#xff0c;被发现了&#xff01;4 喵喵&#xff1a;你当我傻吗&#xff1f;5 今晚可不可以到你家吃饭6 吵架后女生的夜晚vs吵架后男生的夜晚太真实了7 打游戏时候 对方队友和我方…

项目背景介绍

Adventure 项目&#xff08;1&#xff09; 墨翟坐在办公室里&#xff0c;正和秘书 Alan 开会&#xff0c;讨论着一件让他和 Alan 都很烦心的事情。Adventure 在全球都有工厂&#xff0c;制造各种不同的产品。作为制造部门的负责人&#xff0c;墨翟需要每个月了解各个工厂的运行…

不想升Win11?Win10新版马上到!

微软正式宣布 Windows 10 操作系统的下一个功能更新&#xff1a;Windows 10 版本 21H2。微软表示&#xff1a;虽然我们对下一代 Windows 11 感到兴奋&#xff0c;但也专注于支持 Windows 10 上超过 13 亿台活跃设备。当人们继续在混合和远程环境中工作、学习和娱乐时&#xff0…

娱乐项目和女朋友哪个重要?

1 这招风卷残云我只演示一遍&#xff0c;看好了2 摄影师给男生拍照VS给女生拍照3 这个视力表是永远不会近视的4 娱乐项目和女朋友哪个重要&#xff1f;小伙子你飘了啊5 最怕空气突然安静6 “灵魂六问”7 原来是这样周末愉快↓ ↓ ↓

这些高校竟因名字太“坑爹”被误会为三本?盘点九所实力强劲但被名字耽误的大学...

全世界只有3.14 % 的人关注了爆炸吧知识有这样一个段子&#xff1a;西北某地一学生&#xff0c;志存高远&#xff0c;矢志从医。首次高考考入泸州医学院&#xff0c;到校后发现不理想&#xff0c;果断返乡复读。一年后成功考入四川医科大学&#xff0c;到校后傻眼了&#xff0c…

【全】.net core平台单元/集成测试结果、覆盖率、圈复杂度到可视化HTML报告之路...

.net core 平台的测试框架有好几个可供选择&#xff0c;内置的MSTest框架、NUnit框架以及强大好用的xUnit框架&#xff0c;依托宇宙最强的编辑器Visual Studio&#xff0c;可以开展非常友好的测试以及快乐的展示测试的结果。如果仅限于此&#xff0c;那么这篇文章对你来说就是多…

哪种HTML列表会自动编号,HTML列表的种类

HTML 支持有序、无序和定义列表无序列表无序列表是一个项目的列表&#xff0c;此列项目使用粗体圆点(典型的小黑圆圈)进行标记。无序列表始于 标签。每个列表项始于 。(推荐学习&#xff1a;HTML入门教程)CoffeeMilk浏览器显示如下&#xff1a;CoffeeMilk列表项内部可以使用段落…

Android之AsyncTask异步任务详解总结

Android 多线程----AsyncTask异步任务详解 【正文】 本文将讲解一下Android的多线程的知识&#xff0c;以及如何通过AsyncTask机制来实现线程之间的通信。 一、Android当中的多线程&#xff1a; 在Android当中&#xff0c;当一个应用程序的组件启动的时候&#xff0c;并且没有其…

docker源码_使用docker、Jenkins、gitlee、springboot、搭建个人博客网站 并实现CI/CD 外加机器人提醒...

看朱成碧思纷纷&#xff0c;憔悴支离为忆君。--- barcke前言:服务器用的是云服务器买的阿里的linux、jdk1.8、docker服务端使用的为阿里的docker镜像仓库、mysql使用5.7版本的、redis使用最新版即可、文件服务使用的阿里的oss.项目采用jib推送docker镜像.附录: git源码地址—-h…

初次见面,如何令人永远难忘

1 初次见面&#xff0c;如何令人永远难忘2 见到熟人和见到偶像的区别3 真正的好朋友是在最紧急的时刻帮你一把的那个人4 当你正在减肥时&#xff0c;你朋友约你出去吃饭5 被这样的友谊感动到了6 等我老了也要和大爷一样做一个时尚的人不说别的大爷好酷↓ ↓ ↓

号称迄今为止最快,.NET6带来了什么?

北京时间11月8号午夜&#xff0c;.NET6正式发布。该版本经历了一万多次Git提交&#xff0c;号称迄今为止最快的.NET&#xff0c;究竟有哪些亮点呢&#xff1f;1LTS版本&#xff0c;发布前经过了长期的线上生产压力测试&#xff1b;2性能提升&#xff0c;包括文件I/O&#xff0c…

linux 文件系统的管理 (硬盘)

RH133—Unit4 文件系统的管理 一、系统在初始化时如何识别硬盘 1、系统初始时根据MBR的信息来识别硬盘&#xff0c;其中包括了一些执行文件就来载入系统&#xff0c;这些执行文件就是MBR里前面446bytes里的boot loader 程式&#xff0c;而后面的16X4的空间就是存储分区表信息的…

Android之多线程----异步消息处理机制之Handler详解

一、handler的引入&#xff1a; 我们都知道&#xff0c;Android UI是线程不安全的&#xff0c;如果在子线程中尝试进行UI操作&#xff0c;程序就有可能会崩溃。相信大家在日常的工作当中都会经常遇到这个问题&#xff0c;解决的方案应该也是早已烂熟于心&#xff0c;即创建一个…

colorkey唇釉是否安全_colorkey空气唇釉,19/支

国货之光来喽 !!!!超火的colorkey空气唇釉给你们安排上 !!!R601 酒酿梅子超酷超性感的一支 !!这个颜色是偏调但是不显老的深草莓红 一点都不挑皮 谁涂谁白一个度&#xff5e;厚厚的涂一层气场值upup !R608 焦糖红棕偏橘棕调的红棕板栗 !!薄涂厚涂都显白、显气质&#xff01;味道…

初识Ildasm.exe——IL反编译的实用工具(转自Youngman)

Ildasm.exe 概要&#xff1a; 一.前言&#xff1a; 微软的IL反编译实用程序——Ildasm.exe&#xff0c;可以对可执行文件&#xff08;ex&#xff0c;经典的控制台Hello World 的 exe 可执行文件&#xff09;抽取出 IL 代码&#xff0c;并且给出命名空间以及类的视图。在讲述如何…

就想问问你们,这种女朋友从哪里来的?

1 女朋友从哪里来的2 能养好这宠物的对女朋友包容心肯定不赖3 墙都不扶就服这些停车的人4 成功避过所有的球&#xff0c;将白球打入底袋5 谁知道我六年级经历了什么6 这设计&#xff0c;做到了真正意义上的防盗7 这就是我想要的生活面朝大海、春暖花开我也想梦想成真↓ …

基于事件驱动架构构建微服务第10部分:在docker容器内运行单元测试

原文链接&#xff1a;https://logcorner.com/building-microservices-through-event-driven-architecture-part11-run-unit-tests-inside-a-docker-container/在本教程中&#xff0c;我将展示如何在docker容器中运行单元测试。因为我将使用kubernetes在容器中运行微服务&#x…

【iOS-Cocos2d游戏开发之二十】精灵的基础知识点总汇(位图操作/贴图更换/重排z轴等)以及利用CCSprite与CCLayerColor制作简单遮盖层!...

为什么80%的码农都做不了架构师&#xff1f;>>> 李华明Himi 原创,转载务必在明显处注明&#xff1a; 转载自 【黑米GameDev街区】 原文链接: http://www.himigame.com/iphone-cocos2d/516.html 最近写了不少Cocos2d的博文了&#xff0c;那么由于Himi介绍的一般都是…

中柏平板u盘启动_大冶深圳东莞平板硫化机推选得新科技自动化

大冶深圳东莞平板硫化机推选得新科技自动化东莞市得新科技有限公司, 在国内外的销售机器公司。公司位于广东省东莞市。企业致力于点胶设备&#xff0c;硅胶设备&#xff0c;纺织品涂层的先进技术、检测经验发展国外&#xff0c;全面提升国外产品质量&#xff0c;推动国内行业健…

Console-算法-递归算法示例

ylbtech-Arithmetic:Console-算法-递归算法示例1.A&#xff0c;案例-- -- ylb&#xff1a;算法-- type&#xff1a;递归算法-- thankyou:sunshine, 谢谢你的默默付出-- 10:50 2012-04-06-- 1.B&#xff0c;解决方案1.B.1,阶乘 using System;namespace ConsoleApplication1 {cla…